Compare commits

...

11 commits

Author SHA1 Message Date
Timothée Jaussoin
5930e78586 Fix FLEXIAPI-132 2024-01-24 16:52:35 +01:00
Timothée Jaussoin
4f016c70a3 Fix FLEXIAPI-136 Refactor the Web Panel toggle mechanism and move it to a proper Middleware 2024-01-23 16:05:47 +00:00
Timothée Jaussoin
5b86cc75c9 Fix FLEXIAPI-133 Use the correct breadcrumb on create and fix a password update related issue on update - 1.4 2024-01-23 15:34:07 +00:00
Timothée Jaussoin
10a29b7420 Fix #135 Refactor the password algorithms code 2023-12-18 16:19:12 +00:00
Timothée Jaussoin
adbf8320e7 Fix #133 Make the MySQL connection unstrict 2023-12-14 16:02:05 +01:00
Timothée Jaussoin
07f2048c10 Release the 1.4.0 2023-12-06 13:34:51 +00:00
Timothée Jaussoin
3e23ebcc70 Merge branch 'release/1.4' 2023-11-30 17:17:11 +01:00
Timothée Jaussoin
c770798493 Fix #128 Add a DotEnv toggle to enable/disable the X-Linphone-Provisioning header 2023-11-30 16:15:44 +00:00
Timothée Jaussoin
4d9a19f8cf Fix #119 Add a X-Linphone-Provisioning required header to the provisioning... 2023-11-13 14:14:42 +00:00
Timothée Jaussoin
b70fc27fea Reorganize the statistics filters form for better readability 2023-11-13 10:33:37 +00:00
Timothée Jaussoin
1c0d069afc Branch the 1.4
Complete the CHANGELOG with new features and fixes
Update the dependencies
2023-11-09 14:55:47 +01:00
29 changed files with 376 additions and 236 deletions

View file

@ -1,5 +1,24 @@
# Flexisip Account Manager Changelog
v1.5
----
v1.4.4
------
- Fix FLEXIAPI-136 Refactor the Web Panel toggle mechanism and move it to a proper Middleware
v1.4.3
------
- Fix FLEXIAPI-133 Use the correct breadcrumb on create and fix a password update related issue on update
v1.4.2
------
- Fix #135 Refactor the password algorithms code
v1.4.1
------
- Fix #133 Make the MySQL connection unstrict
v1.4
----
- Redesign and refactoring of the main UI and panel flows

View file

@ -74,7 +74,7 @@ deb-only:
fakeroot alien -g -k --scripts $(OUTPUT_DIR)/rpmbuild/tmp.rpm
rm -r $(OUTPUT_DIR)/rpmbuild
rm -rf $(OUTPUT_DIR)/*.orig
sed -i 's/Depends:.*/Depends: $${shlibs:Depends}, php (>= 8.0), php-xml, php-pdo, php-gd, php-redis, php-mysql, php-mbstring, php-sqlite3/g' $(OUTPUT_DIR)/bc-flexisip-account-manager*/debian/control
sed -i 's/Depends:.*/Depends: $${shlibs:Depends}, php (>= 8.2), php8.2-xml, php8.2-pdo, php8.2-gd, php8.2-redis, php8.2-mysql, php8.2-mbstring, php8.2-sqlite3/g' $(OUTPUT_DIR)/bc-flexisip-account-manager*/debian/control
cd `ls -rt $(OUTPUT_DIR) | tail -1` && dpkg-buildpackage --no-sign
@echo "📦✅ DEB Package Created"

View file

@ -147,18 +147,6 @@ For the REST API, the `/api` page contains all the required documentation to aut
FlexiAPI is shipped with several console commands that you can launch using the `artisan` executable available at the root of this project.
### Migrate an old database
FlexiAPI needs an empty database to run its migration. The following console command allow you to import simultanously an exisiting Flexisip database and the old FlexiAPI SQLite database file (if you have one) in the new one. To do so, please specify the new database configuration in the `.env` file and run the following command.
The migration script requires at least 300mb of memory to run. You should edit the `memory_limit` in the `php.ini` file to increase it.
php artisan db:import {old_dbname} {old_sqlite_file_path?} --username={old_username} --password={old_password}
Several other parameters are also available to customize the migration process, you can list them all using the command documentation.
php artisan -h db:import
### Create an admin account
Create an admin account, an API Key will also be generated along the way, it might expire after a while.

View file

@ -26,10 +26,12 @@ ACCOUNT_EMAIL_UNIQUE=false # Emails are unique between all the accounts
ACCOUNT_CONSUME_EXTERNAL_ACCOUNT_ON_CREATE=false
ACCOUNT_BLACKLISTED_USERNAMES=
ACCOUNT_USERNAME_REGEX="^[a-z0-9+_.-]*$"
ACCOUNT_DEFAULT_PASSWORD_ALGORITHM=SHA-256 # Can ONLY be MD5 or SHA-256 in capital, default to SHA-256
# Account provisioning
ACCOUNT_PROVISIONING_RC_FILE=
ACCOUNT_PROVISIONING_OVERWRITE_ALL=
ACCOUNT_PROVISIONING_USE_X_LINPHONE_PROVISIONING_HEADER=true
# Instance specific parameters
INSTANCE_COPYRIGHT= # Simple text displayed in the page footer

View file

@ -345,8 +345,10 @@ class Account extends Authenticatable
return !empty($this->recovery_code) && $this->updated_at->greaterThan($oneHourAgo);
}
public function updatePassword($newPassword, string $algorithm = 'SHA-256')
public function updatePassword(string $newPassword, ?string $algorithm = null)
{
$algorithm = $algorithm ?? config('app.account_default_password_algorithm');
$this->passwords()->delete();
$password = new Password;
@ -356,14 +358,6 @@ class Account extends Authenticatable
$password->save();
}
public function fillPassword(Request $request)
{
if ($request->filled('password')) {
$this->algorithm = $request->has('password_sha256') ? 'SHA-256' : 'MD5';
$this->updatePassword($request->get('password'), $this->algorithm);
}
}
public function toVcard4()
{
$vcard = 'BEGIN:VCARD

View file

@ -28,6 +28,14 @@ use League\CommonMark\Extension\HeadingPermalink\HeadingPermalinkExtension;
use League\CommonMark\Extension\TableOfContents\TableOfContentsExtension;
use Illuminate\Support\Facades\DB;
function passwordAlgorithms(): array
{
return [
'MD5' => 'md5',
'SHA-256' => 'sha256',
];
}
function generateNonce(): string
{
return Str::random(32);
@ -45,9 +53,7 @@ function generateValidNonce(Account $account): string
function bchash(string $username, string $domain, string $password, string $algorithm = 'MD5')
{
$algos = ['MD5' => 'md5', 'SHA-256' => 'sha256'];
return hash($algos[$algorithm], $username . ':' . $domain . ':' . $password);
return hash(passwordAlgorithms()[$algorithm], $username . ':' . $domain . ':' . $password);
}
function generatePin()
@ -86,11 +92,6 @@ function markdownDocumentationView($view): string
);
}
function publicRegistrationEnabled(): bool
{
return (config('app.public_registration'));
}
function isRegularExpression($string): bool
{
set_error_handler(function () {

View file

@ -45,7 +45,7 @@ class PasswordController extends Controller
$account->activated = true;
$account->save();
$account->updatePassword($request->get('password'), 'SHA-256');
$account->updatePassword($request->get('password'));
if ($account->passwords()->count() > 0) {
Log::channel('events')->info('Web: Password changed', ['id' => $account->identifier]);

View file

@ -124,7 +124,8 @@ class ProvisioningController extends Controller
private function generateProvisioning(Request $request, Account $account = null)
{
if (!$request->hasHeader('x-linphone-provisioning')) {
if (!$request->hasHeader('x-linphone-provisioning')
&& config('app.provisioning_use_x_linphone_provisioning_header')) {
abort(400, 'x-linphone-provisioning header is missing');
}
@ -136,17 +137,14 @@ class ProvisioningController extends Controller
}
$dom = new \DOMDocument('1.0', 'UTF-8');
$xpath = new \DOMXpath($dom);
$config = $dom->createElement('config');
$config->setAttribute('xmlns', 'http://www.linphone.org/xsds/lpconfig.xsd');
//$config->setAttribute('xsi:schemaLocation', 'http://www.linphone.org/xsds/lpconfig.xsd lpconfig.xsd');
//$config->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
$dom->appendChild($config);
// Default RC file handling
$rcFile = config('app.provisioning_rc_file');
$proxyConfigIndex = 0;
$authInfoIndex = 0;
if (file_exists($rcFile)) {
$rc = parse_ini_file($rcFile, true);
@ -155,12 +153,6 @@ class ProvisioningController extends Controller
$section = $dom->createElement('section');
$section->setAttribute('name', $sectionName);
if (Str::startsWith($sectionName, "proxy_config_")) {
$proxyConfigIndex++;
} elseif (Str::startsWith($sectionName, "auth_info_")) {
$authInfoIndex++;
}
foreach ($values as $key => $value) {
$entry = $dom->createElement('entry', $value);
$entry->setAttribute('name', $key);
@ -186,21 +178,17 @@ class ProvisioningController extends Controller
$config->appendChild($section);
if ($account) {
$section = $dom->createElement('section');
$section->setAttribute('name', 'proxy_' . $proxyConfigIndex);
$section = $xpath->query("//section[@name='proxy_0']")->item(0);
if ($section == null) {
$section = $dom->createElement('section');
$section->setAttribute('name', 'proxy_0');
}
$entry = $dom->createElement('entry', $account->fullIdentifier);
$entry->setAttribute('name', 'reg_identity');
$section->appendChild($entry);
$entry = $dom->createElement('entry', 1);
$entry->setAttribute('name', 'reg_sendregister');
$section->appendChild($entry);
$entry = $dom->createElement('entry', 'push_notification');
$entry->setAttribute('name', 'refkey');
$section->appendChild($entry);
// Complete the section with the Proxy hook
if (function_exists('provisioningProxyHook')) {
provisioningProxyHook($section, $request, $account);
@ -209,10 +197,15 @@ class ProvisioningController extends Controller
$config->appendChild($section);
$passwords = $account->passwords()->get();
$authInfoIndex = 0;
foreach ($passwords as $password) {
$section = $dom->createElement('section');
$section->setAttribute('name', 'auth_info_' . $authInfoIndex);
$section = $xpath->query("//section[@name='auth_info_" . $authInfoIndex . "']")->item(0);
if ($section == null) {
$section = $dom->createElement('section');
$section->setAttribute('name', 'auth_info_' . $authInfoIndex);
}
$entry = $dom->createElement('entry', $account->username);
$entry->setAttribute('name', 'username');
@ -243,8 +236,6 @@ class ProvisioningController extends Controller
$authInfoIndex++;
}
$proxyConfigIndex++;
}
// Complete the section with the Auth hook

View file

@ -98,7 +98,7 @@ class AccountController extends Controller
$account->save();
$account->phone = $request->get('phone');
$account->fillPassword($request);
$account->updatePassword($request->get('password'));
$account->refresh();
$account->setRole($request->get('role'));
@ -136,8 +136,8 @@ class AccountController extends Controller
$account->phone = $request->get('phone');
if ($request->filled('password') && $request->filled('password_confirmation')) {
$account->fillPassword($request);
if ($request->get('password')) {
$account->updatePassword($request->get('password'));
}
$account->setRole($request->get('role'));

View file

@ -31,15 +31,19 @@ use App\Account;
use App\AccountCreationToken;
use App\AccountTombstone;
use App\Alias;
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
use App\Http\Requests\CreateAccountRequest;
use App\Libraries\OvhSMS;
use App\Mail\RegisterConfirmation;
use App\Rules\AccountCreationToken as RulesAccountCreationToken;
use App\Rules\BlacklistedUsername;
use App\Rules\NoUppercase;
use App\Rules\SIPUsername;
use App\Rules\WithoutSpaces;
use App\Rules\PasswordAlgorithm;
use App\Services\AccountService;
class AccountController extends Controller
@ -104,7 +108,7 @@ class AccountController extends Controller
}),
'filled',
],
'algorithm' => 'required|in:SHA-256,MD5',
'algorithm' => ['required', new PasswordAlgorithm],
'password' => 'required|filled',
'domain' => 'min:3',
'email' => config('app.account_email_unique')

View file

@ -19,11 +19,13 @@
namespace App\Http\Controllers\Api\Account;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
use App\Rules\PasswordAlgorithm;
use App\Mail\ConfirmedRegistration;
class PasswordController extends Controller
@ -31,7 +33,7 @@ class PasswordController extends Controller
public function update(Request $request)
{
$request->validate([
'algorithm' => 'required|in:SHA-256,MD5',
'algorithm' => ['required', new PasswordAlgorithm],
'password' => 'required',
]);

View file

@ -33,6 +33,7 @@ use App\ContactsList;
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
use App\Http\Requests\CreateAccountRequest;
use App\Http\Requests\UpdateAccountRequest;
use App\Rules\PasswordAlgorithm;
use App\Services\AccountService;
class AccountController extends Controller
@ -109,7 +110,7 @@ class AccountController extends Controller
public function store(CreateAccountRequest $request)
{
$request->validate([
'algorithm' => 'required|in:SHA-256,MD5',
'algorithm' => ['required', new PasswordAlgorithm],
'admin' => 'boolean|nullable',
'activated' => 'boolean|nullable',
'confirmation_key_expires' => [
@ -159,7 +160,7 @@ class AccountController extends Controller
public function update(UpdateAccountRequest $request, int $accountId)
{
$request->validate([
'algorithm' => 'required|in:SHA-256,MD5',
'algorithm' => ['required', new PasswordAlgorithm],
'admin' => 'boolean|nullable',
'activated' => 'boolean|nullable'
]);

View file

@ -72,6 +72,7 @@ class Kernel extends HttpKernel
'auth.admin' => \App\Http\Middleware\AuthenticateAdmin::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.digest_or_key' => \App\Http\Middleware\AuthenticateDigestOrKey::class,
'web_panel_enabled' => \App\Http\Middleware\IsWebPanelEnabled::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,

View file

@ -14,7 +14,7 @@ class Authenticate extends Middleware
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
if (!$request->expectsJson()) {
return route('account.home');
}
}

View file

@ -30,11 +30,6 @@ use Validator;
class AuthenticateDigestOrKey
{
const ALGORITHMS = [
'MD5' => 'md5',
'SHA-256' => 'sha256',
];
/**
* Handle an incoming request.
*
@ -106,7 +101,7 @@ class AuthenticateDigestOrKey
'cnonce' => 'required',
'algorithm' => [
'required',
Rule::in(array_keys(self::ALGORITHMS)),
Rule::in(array_keys(passwordAlgorithms())),
],
'username' => 'required|in:'.$username,
])->validate();
@ -130,7 +125,7 @@ class AuthenticateDigestOrKey
return $this->generateUnauthorizedResponse($account, 'Wrong algorithm');
}
$hash = self::ALGORITHMS[$auth['algorithm']];
$hash = passwordAlgorithms()[$auth['algorithm']];
// Hashing and checking
$a1 = $password->algorithm == 'CLRTXT'
@ -208,14 +203,14 @@ class AuthenticateDigestOrKey
foreach ($account->passwords as $password) {
if ($password->algorithm == 'CLRTXT') {
foreach (array_keys(self::ALGORITHMS) as $algorithm) {
foreach (array_keys(passwordAlgorithms()) as $algorithm) {
array_push(
$headers,
$this->generateAuthHeader($resolvedRealm, $algorithm, $nonce)
);
}
break;
} else if (\in_array($password->algorithm, array_keys(self::ALGORITHMS))) {
} else if (\in_array($password->algorithm, array_keys(passwordAlgorithms()))) {
array_push(
$headers,
$this->generateAuthHeader($resolvedRealm, $password->algorithm, $nonce)

View file

@ -0,0 +1,42 @@
<?php
/*
Flexisip Account Manager is a set of tools to manage SIP accounts.
Copyright (C) 2020 Belledonne Communications SARL, All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class IsWebPanelEnabled
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse) $next
* @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
*/
public function handle(Request $request, Closure $next)
{
if (!$request->expectsJson() && config('app.web_panel')) {
return $next($request);
}
return redirect()->route('about');
}
}

View file

@ -39,7 +39,6 @@ class UpdateAccountRequest extends FormRequest
config('app.account_email_unique') ? Rule::unique('accounts', 'email')->ignore($this->route('account_id')) : null
],
'role' => 'in:admin,end_user',
'password_sha256' => 'nullable|min:3',
'dtmf_protocol' => 'nullable|in:' . Account::dtmfProtocolsRule(),
'phone' => [
'nullable',

View file

@ -0,0 +1,18 @@
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
class PasswordAlgorithm implements Rule
{
public function passes($attribute, $value)
{
return in_array($value, array_keys(passwordAlgorithms()));
}
public function message()
{
return 'The password algorithm must be in ' . implode(', ', array_keys(passwordAlgorithms()));
}
}

View file

@ -73,7 +73,7 @@ class AccountService
$account->provision();
$account->save();
$account->updatePassword($request->get('password'), $request->has('algorithm') ? $request->get('algorithm') : 'SHA-256');
$account->updatePassword($request->get('password'), $request->get('algorithm'));
if ($this->api) {
$token = AccountCreationToken::where('token', $request->get('account_creation_token'))->first();

279
flexiapi/composer.lock generated
View file

@ -241,6 +241,75 @@
],
"time": "2023-01-15T23:15:59+00:00"
},
{
"name": "carbonphp/carbon-doctrine-types",
"version": "2.0.0",
"source": {
"type": "git",
"url": "https://github.com/CarbonPHP/carbon-doctrine-types.git",
"reference": "67a77972b9f398ae7068dabacc39c08aeee170d5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/CarbonPHP/carbon-doctrine-types/zipball/67a77972b9f398ae7068dabacc39c08aeee170d5",
"reference": "67a77972b9f398ae7068dabacc39c08aeee170d5",
"shasum": ""
},
"require": {
"php": "^7.4 || ^8.0"
},
"conflict": {
"doctrine/dbal": "<3.7.0 || >=4.0.0"
},
"require-dev": {
"doctrine/dbal": "^3.7.0",
"nesbot/carbon": "^2.71.0 || ^3.0.0",
"phpunit/phpunit": "^10.3"
},
"type": "library",
"autoload": {
"psr-4": {
"Carbon\\Doctrine\\": "src/Carbon/Doctrine/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "KyleKatarn",
"email": "kylekatarnls@gmail.com"
}
],
"description": "Types to use Carbon in Doctrine",
"keywords": [
"carbon",
"date",
"datetime",
"doctrine",
"time"
],
"support": {
"issues": "https://github.com/CarbonPHP/carbon-doctrine-types/issues",
"source": "https://github.com/CarbonPHP/carbon-doctrine-types/tree/2.0.0"
},
"funding": [
{
"url": "https://github.com/kylekatarnls",
"type": "github"
},
{
"url": "https://opencollective.com/Carbon",
"type": "open_collective"
},
{
"url": "https://tidelift.com/funding/github/packagist/nesbot/carbon",
"type": "tidelift"
}
],
"time": "2023-10-01T14:29:01+00:00"
},
{
"name": "dasprid/enum",
"version": "1.0.5",
@ -461,16 +530,16 @@
},
{
"name": "doctrine/dbal",
"version": "3.7.1",
"version": "3.7.2",
"source": {
"type": "git",
"url": "https://github.com/doctrine/dbal.git",
"reference": "5b7bd66c9ff58c04c5474ab85edce442f8081cb2"
"reference": "0ac3c270590e54910715e9a1a044cc368df282b2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/5b7bd66c9ff58c04c5474ab85edce442f8081cb2",
"reference": "5b7bd66c9ff58c04c5474ab85edce442f8081cb2",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/0ac3c270590e54910715e9a1a044cc368df282b2",
"reference": "0ac3c270590e54910715e9a1a044cc368df282b2",
"shasum": ""
},
"require": {
@ -486,7 +555,7 @@
"doctrine/coding-standard": "12.0.0",
"fig/log-test": "^1",
"jetbrains/phpstorm-stubs": "2023.1",
"phpstan/phpstan": "1.10.35",
"phpstan/phpstan": "1.10.42",
"phpstan/phpstan-strict-rules": "^1.5",
"phpunit/phpunit": "9.6.13",
"psalm/plugin-phpunit": "0.18.4",
@ -554,7 +623,7 @@
],
"support": {
"issues": "https://github.com/doctrine/dbal/issues",
"source": "https://github.com/doctrine/dbal/tree/3.7.1"
"source": "https://github.com/doctrine/dbal/tree/3.7.2"
},
"funding": [
{
@ -570,7 +639,7 @@
"type": "tidelift"
}
],
"time": "2023-10-06T05:06:20+00:00"
"time": "2023-11-19T08:06:58+00:00"
},
{
"name": "doctrine/deprecations",
@ -1453,16 +1522,16 @@
},
{
"name": "guzzlehttp/guzzle",
"version": "7.8.0",
"version": "7.8.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "1110f66a6530a40fe7aea0378fe608ee2b2248f9"
"reference": "41042bc7ab002487b876a0683fc8dce04ddce104"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/1110f66a6530a40fe7aea0378fe608ee2b2248f9",
"reference": "1110f66a6530a40fe7aea0378fe608ee2b2248f9",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104",
"reference": "41042bc7ab002487b876a0683fc8dce04ddce104",
"shasum": ""
},
"require": {
@ -1477,11 +1546,11 @@
"psr/http-client-implementation": "1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.1",
"bamarni/composer-bin-plugin": "^1.8.2",
"ext-curl": "*",
"php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999",
"php-http/message-factory": "^1.1",
"phpunit/phpunit": "^8.5.29 || ^9.5.23",
"phpunit/phpunit": "^8.5.36 || ^9.6.15",
"psr/log": "^1.1 || ^2.0 || ^3.0"
},
"suggest": {
@ -1559,7 +1628,7 @@
],
"support": {
"issues": "https://github.com/guzzle/guzzle/issues",
"source": "https://github.com/guzzle/guzzle/tree/7.8.0"
"source": "https://github.com/guzzle/guzzle/tree/7.8.1"
},
"funding": [
{
@ -1575,28 +1644,28 @@
"type": "tidelift"
}
],
"time": "2023-08-27T10:20:53+00:00"
"time": "2023-12-03T20:35:24+00:00"
},
{
"name": "guzzlehttp/promises",
"version": "2.0.1",
"version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/promises.git",
"reference": "111166291a0f8130081195ac4556a5587d7f1b5d"
"reference": "bbff78d96034045e58e13dedd6ad91b5d1253223"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/promises/zipball/111166291a0f8130081195ac4556a5587d7f1b5d",
"reference": "111166291a0f8130081195ac4556a5587d7f1b5d",
"url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223",
"reference": "bbff78d96034045e58e13dedd6ad91b5d1253223",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.1",
"phpunit/phpunit": "^8.5.29 || ^9.5.23"
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.36 || ^9.6.15"
},
"type": "library",
"extra": {
@ -1642,7 +1711,7 @@
],
"support": {
"issues": "https://github.com/guzzle/promises/issues",
"source": "https://github.com/guzzle/promises/tree/2.0.1"
"source": "https://github.com/guzzle/promises/tree/2.0.2"
},
"funding": [
{
@ -1658,20 +1727,20 @@
"type": "tidelift"
}
],
"time": "2023-08-03T15:11:55+00:00"
"time": "2023-12-03T20:19:20+00:00"
},
{
"name": "guzzlehttp/psr7",
"version": "2.6.1",
"version": "2.6.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "be45764272e8873c72dbe3d2edcfdfcc3bc9f727"
"reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/be45764272e8873c72dbe3d2edcfdfcc3bc9f727",
"reference": "be45764272e8873c72dbe3d2edcfdfcc3bc9f727",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221",
"reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221",
"shasum": ""
},
"require": {
@ -1685,9 +1754,9 @@
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.1",
"bamarni/composer-bin-plugin": "^1.8.2",
"http-interop/http-factory-tests": "^0.9",
"phpunit/phpunit": "^8.5.29 || ^9.5.23"
"phpunit/phpunit": "^8.5.36 || ^9.6.15"
},
"suggest": {
"laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
@ -1758,7 +1827,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/2.6.1"
"source": "https://github.com/guzzle/psr7/tree/2.6.2"
},
"funding": [
{
@ -1774,32 +1843,38 @@
"type": "tidelift"
}
],
"time": "2023-08-27T10:13:57+00:00"
"time": "2023-12-03T20:05:35+00:00"
},
{
"name": "guzzlehttp/uri-template",
"version": "v1.0.2",
"version": "v1.0.3",
"source": {
"type": "git",
"url": "https://github.com/guzzle/uri-template.git",
"reference": "61bf437fc2197f587f6857d3ff903a24f1731b5d"
"reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/uri-template/zipball/61bf437fc2197f587f6857d3ff903a24f1731b5d",
"reference": "61bf437fc2197f587f6857d3ff903a24f1731b5d",
"url": "https://api.github.com/repos/guzzle/uri-template/zipball/ecea8feef63bd4fef1f037ecb288386999ecc11c",
"reference": "ecea8feef63bd4fef1f037ecb288386999ecc11c",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
"symfony/polyfill-php80": "^1.17"
"symfony/polyfill-php80": "^1.24"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.1",
"phpunit/phpunit": "^8.5.19 || ^9.5.8",
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.36 || ^9.6.15",
"uri-template/tests": "1.0.0"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\UriTemplate\\": "src"
@ -1838,7 +1913,7 @@
],
"support": {
"issues": "https://github.com/guzzle/uri-template/issues",
"source": "https://github.com/guzzle/uri-template/tree/v1.0.2"
"source": "https://github.com/guzzle/uri-template/tree/v1.0.3"
},
"funding": [
{
@ -1854,7 +1929,7 @@
"type": "tidelift"
}
],
"time": "2023-08-27T10:19:19+00:00"
"time": "2023-12-03T19:50:20+00:00"
},
{
"name": "laravel/framework",
@ -2056,16 +2131,16 @@
},
{
"name": "laravel/serializable-closure",
"version": "v1.3.2",
"version": "v1.3.3",
"source": {
"type": "git",
"url": "https://github.com/laravel/serializable-closure.git",
"reference": "076fe2cf128bd54b4341cdc6d49b95b34e101e4c"
"reference": "3dbf8a8e914634c48d389c1234552666b3d43754"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/076fe2cf128bd54b4341cdc6d49b95b34e101e4c",
"reference": "076fe2cf128bd54b4341cdc6d49b95b34e101e4c",
"url": "https://api.github.com/repos/laravel/serializable-closure/zipball/3dbf8a8e914634c48d389c1234552666b3d43754",
"reference": "3dbf8a8e914634c48d389c1234552666b3d43754",
"shasum": ""
},
"require": {
@ -2112,7 +2187,7 @@
"issues": "https://github.com/laravel/serializable-closure/issues",
"source": "https://github.com/laravel/serializable-closure"
},
"time": "2023-10-17T13:38:16+00:00"
"time": "2023-11-08T14:08:06+00:00"
},
{
"name": "league/commonmark",
@ -2304,16 +2379,16 @@
},
{
"name": "league/flysystem",
"version": "3.19.0",
"version": "3.23.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem.git",
"reference": "1b2aa10f2326e0351399b8ce68e287d8e9209a83"
"reference": "d4ad81e2b67396e33dc9d7e54ec74ccf73151dcc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/1b2aa10f2326e0351399b8ce68e287d8e9209a83",
"reference": "1b2aa10f2326e0351399b8ce68e287d8e9209a83",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/d4ad81e2b67396e33dc9d7e54ec74ccf73151dcc",
"reference": "d4ad81e2b67396e33dc9d7e54ec74ccf73151dcc",
"shasum": ""
},
"require": {
@ -2341,7 +2416,7 @@
"friendsofphp/php-cs-fixer": "^3.5",
"google/cloud-storage": "^1.23",
"microsoft/azure-storage-blob": "^1.1",
"phpseclib/phpseclib": "^3.0.14",
"phpseclib/phpseclib": "^3.0.34",
"phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.5.11|^10.0",
"sabre/dav": "^4.3.1"
@ -2378,7 +2453,7 @@
],
"support": {
"issues": "https://github.com/thephpleague/flysystem/issues",
"source": "https://github.com/thephpleague/flysystem/tree/3.19.0"
"source": "https://github.com/thephpleague/flysystem/tree/3.23.0"
},
"funding": [
{
@ -2390,20 +2465,20 @@
"type": "github"
}
],
"time": "2023-11-07T09:04:28+00:00"
"time": "2023-12-04T10:16:17+00:00"
},
{
"name": "league/flysystem-local",
"version": "3.19.0",
"version": "3.23.0",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/flysystem-local.git",
"reference": "8d868217f9eeb4e9a7320db5ccad825e9a7a4076"
"reference": "5cf046ba5f059460e86a997c504dd781a39a109b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/8d868217f9eeb4e9a7320db5ccad825e9a7a4076",
"reference": "8d868217f9eeb4e9a7320db5ccad825e9a7a4076",
"url": "https://api.github.com/repos/thephpleague/flysystem-local/zipball/5cf046ba5f059460e86a997c504dd781a39a109b",
"reference": "5cf046ba5f059460e86a997c504dd781a39a109b",
"shasum": ""
},
"require": {
@ -2438,7 +2513,7 @@
],
"support": {
"issues": "https://github.com/thephpleague/flysystem-local/issues",
"source": "https://github.com/thephpleague/flysystem-local/tree/3.19.0"
"source": "https://github.com/thephpleague/flysystem-local/tree/3.23.0"
},
"funding": [
{
@ -2450,7 +2525,7 @@
"type": "github"
}
],
"time": "2023-11-06T20:35:28+00:00"
"time": "2023-12-04T10:14:46+00:00"
},
{
"name": "league/mime-type-detection",
@ -2732,19 +2807,20 @@
},
{
"name": "nesbot/carbon",
"version": "2.71.0",
"version": "2.72.0",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
"reference": "98276233188583f2ff845a0f992a235472d9466a"
"reference": "a6885fcbad2ec4360b0e200ee0da7d9b7c90786b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/98276233188583f2ff845a0f992a235472d9466a",
"reference": "98276233188583f2ff845a0f992a235472d9466a",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/a6885fcbad2ec4360b0e200ee0da7d9b7c90786b",
"reference": "a6885fcbad2ec4360b0e200ee0da7d9b7c90786b",
"shasum": ""
},
"require": {
"carbonphp/carbon-doctrine-types": "*",
"ext-json": "*",
"php": "^7.1.8 || ^8.0",
"psr/clock": "^1.0",
@ -2756,8 +2832,8 @@
"psr/clock-implementation": "1.0"
},
"require-dev": {
"doctrine/dbal": "^2.0 || ^3.1.4",
"doctrine/orm": "^2.7",
"doctrine/dbal": "^2.0 || ^3.1.4 || ^4.0",
"doctrine/orm": "^2.7 || ^3.0",
"friendsofphp/php-cs-fixer": "^3.0",
"kylekatarnls/multi-tester": "^2.0",
"ondrejmirtes/better-reflection": "*",
@ -2834,7 +2910,7 @@
"type": "tidelift"
}
],
"time": "2023-09-25T11:31:05+00:00"
"time": "2023-11-28T10:13:25+00:00"
},
{
"name": "nette/schema",
@ -3744,16 +3820,16 @@
},
{
"name": "phpunit/phpunit",
"version": "9.6.13",
"version": "9.6.15",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be"
"reference": "05017b80304e0eb3f31d90194a563fd53a6021f1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/f3d767f7f9e191eab4189abe41ab37797e30b1be",
"reference": "f3d767f7f9e191eab4189abe41ab37797e30b1be",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/05017b80304e0eb3f31d90194a563fd53a6021f1",
"reference": "05017b80304e0eb3f31d90194a563fd53a6021f1",
"shasum": ""
},
"require": {
@ -3827,7 +3903,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.13"
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.15"
},
"funding": [
{
@ -3843,7 +3919,7 @@
"type": "tidelift"
}
],
"time": "2023-09-19T05:39:22+00:00"
"time": "2023-12-01T16:55:19+00:00"
},
{
"name": "psr/cache",
@ -4606,16 +4682,16 @@
},
{
"name": "react/dns",
"version": "v1.11.0",
"version": "v1.12.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/dns.git",
"reference": "3be0fc8f1eb37d6875cd6f0c6c7d0be81435de9f"
"reference": "c134600642fa615b46b41237ef243daa65bb64ec"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/dns/zipball/3be0fc8f1eb37d6875cd6f0c6c7d0be81435de9f",
"reference": "3be0fc8f1eb37d6875cd6f0c6c7d0be81435de9f",
"url": "https://api.github.com/repos/reactphp/dns/zipball/c134600642fa615b46b41237ef243daa65bb64ec",
"reference": "c134600642fa615b46b41237ef243daa65bb64ec",
"shasum": ""
},
"require": {
@ -4625,7 +4701,7 @@
"react/promise": "^3.0 || ^2.7 || ^1.2.1"
},
"require-dev": {
"phpunit/phpunit": "^9.5 || ^4.8.35",
"phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36",
"react/async": "^4 || ^3 || ^2",
"react/promise-timer": "^1.9"
},
@ -4670,7 +4746,7 @@
],
"support": {
"issues": "https://github.com/reactphp/dns/issues",
"source": "https://github.com/reactphp/dns/tree/v1.11.0"
"source": "https://github.com/reactphp/dns/tree/v1.12.0"
},
"funding": [
{
@ -4678,7 +4754,7 @@
"type": "open_collective"
}
],
"time": "2023-06-02T12:45:26+00:00"
"time": "2023-11-29T12:41:06+00:00"
},
{
"name": "react/event-loop",
@ -4754,24 +4830,24 @@
},
{
"name": "react/promise",
"version": "v3.0.0",
"version": "v3.1.0",
"source": {
"type": "git",
"url": "https://github.com/reactphp/promise.git",
"reference": "c86753c76fd3be465d93b308f18d189f01a22be4"
"reference": "e563d55d1641de1dea9f5e84f3cccc66d2bfe02c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/reactphp/promise/zipball/c86753c76fd3be465d93b308f18d189f01a22be4",
"reference": "c86753c76fd3be465d93b308f18d189f01a22be4",
"url": "https://api.github.com/repos/reactphp/promise/zipball/e563d55d1641de1dea9f5e84f3cccc66d2bfe02c",
"reference": "e563d55d1641de1dea9f5e84f3cccc66d2bfe02c",
"shasum": ""
},
"require": {
"php": ">=7.1.0"
},
"require-dev": {
"phpstan/phpstan": "1.10.20 || 1.4.10",
"phpunit/phpunit": "^9.5 || ^7.5"
"phpstan/phpstan": "1.10.39 || 1.4.10",
"phpunit/phpunit": "^9.6 || ^7.5"
},
"type": "library",
"autoload": {
@ -4815,7 +4891,7 @@
],
"support": {
"issues": "https://github.com/reactphp/promise/issues",
"source": "https://github.com/reactphp/promise/tree/v3.0.0"
"source": "https://github.com/reactphp/promise/tree/v3.1.0"
},
"funding": [
{
@ -4823,7 +4899,7 @@
"type": "open_collective"
}
],
"time": "2023-07-11T16:12:49+00:00"
"time": "2023-11-16T16:21:57+00:00"
},
{
"name": "react/socket",
@ -8319,16 +8395,16 @@
},
{
"name": "theseer/tokenizer",
"version": "1.2.1",
"version": "1.2.2",
"source": {
"type": "git",
"url": "https://github.com/theseer/tokenizer.git",
"reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
"reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
"reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
"url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
"reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96",
"shasum": ""
},
"require": {
@ -8357,7 +8433,7 @@
"description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
"support": {
"issues": "https://github.com/theseer/tokenizer/issues",
"source": "https://github.com/theseer/tokenizer/tree/1.2.1"
"source": "https://github.com/theseer/tokenizer/tree/1.2.2"
},
"funding": [
{
@ -8365,7 +8441,7 @@
"type": "github"
}
],
"time": "2021-07-28T10:34:58+00:00"
"time": "2023-11-20T00:12:19+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
@ -9222,23 +9298,24 @@
},
{
"name": "pdepend/pdepend",
"version": "2.15.1",
"version": "2.16.0",
"source": {
"type": "git",
"url": "https://github.com/pdepend/pdepend.git",
"reference": "d12f25bcdfb7754bea458a4a5cb159d55e9950d0"
"reference": "8dfc0c46529e2073fa97986552f80646eedac562"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pdepend/pdepend/zipball/d12f25bcdfb7754bea458a4a5cb159d55e9950d0",
"reference": "d12f25bcdfb7754bea458a4a5cb159d55e9950d0",
"url": "https://api.github.com/repos/pdepend/pdepend/zipball/8dfc0c46529e2073fa97986552f80646eedac562",
"reference": "8dfc0c46529e2073fa97986552f80646eedac562",
"shasum": ""
},
"require": {
"php": ">=5.3.7",
"symfony/config": "^2.3.0|^3|^4|^5|^6.0",
"symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0",
"symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0"
"symfony/config": "^2.3.0|^3|^4|^5|^6.0|^7.0",
"symfony/dependency-injection": "^2.3.0|^3|^4|^5|^6.0|^7.0",
"symfony/filesystem": "^2.3.0|^3|^4|^5|^6.0|^7.0",
"symfony/polyfill-mbstring": "^1.19"
},
"require-dev": {
"easy-doc/easy-doc": "0.0.0|^1.2.3",
@ -9273,7 +9350,7 @@
],
"support": {
"issues": "https://github.com/pdepend/pdepend/issues",
"source": "https://github.com/pdepend/pdepend/tree/2.15.1"
"source": "https://github.com/pdepend/pdepend/tree/2.16.0"
},
"funding": [
{
@ -9281,7 +9358,7 @@
"type": "tidelift"
}
],
"time": "2023-09-28T12:00:56+00:00"
"time": "2023-11-29T08:52:35+00:00"
},
{
"name": "phpmd/phpmd",

View file

@ -32,6 +32,7 @@ return [
'account_email_unique' => env('ACCOUNT_EMAIL_UNIQUE', false),
'blacklisted_usernames' => env('ACCOUNT_BLACKLISTED_USERNAMES', ''),
'account_username_regex' => env('ACCOUNT_USERNAME_REGEX', '^[a-z0-9+_.-]*$'),
'account_default_password_algorithm' => env('ACCOUNT_DEFAULT_PASSWORD_ALGORITHM', 'SHA-256'),
/**
* Time limit before the API Key and related cookie are expired
@ -55,6 +56,7 @@ return [
*/
'provisioning_rc_file' => env('ACCOUNT_PROVISIONING_RC_FILE', ''),
'provisioning_overwrite_all' => env('ACCOUNT_PROVISIONING_OVERWRITE_ALL', false),
'provisioning_use_x_linphone_provisioning_header' => env('ACCOUNT_PROVISIONING_USE_X_LINPHONE_PROVISIONING_HEADER', true),
/**
* Set a global realm for all the accounts, if not set, the account domain

View file

@ -65,7 +65,7 @@ return [
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'strict' => false,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),

View file

@ -37,7 +37,7 @@
@include('parts.recovery')
@if (publicRegistrationEnabled())
@if (config('app.public_registration'))
<br />
<br />

View file

@ -13,7 +13,7 @@
@endif
<a href="{{ route('account.dashboard') }}" class="btn btn-secondary oppose">Cancel</a>
<input form="password_updated" class="btn" type="submit" value="Change">
<input form="password_update" class="btn" type="submit" value="Change">
</header>
<form id="password_update" method="POST" action="{{ route('account.password.update') }}" accept-charset="UTF-8">
@ -24,7 +24,7 @@
<label for="password">New password</label>
</div>
<div>
<input type="password_confirmation" name="password_confirmation" required>
<input type="password" name="password_confirmation" required>
<label for="password_confirmation">Password confirmation</label>
</div>
</form>

View file

@ -20,30 +20,28 @@
<body class="@if (isset($welcome) && $welcome) welcome @endif">
<header>
@if (config('app.web_panel'))
<nav>
<a id="logo" href="{{ route('account.home') }}"><span
class="on_desktop">{{ config('app.name') }}</span></a>
<nav>
<a id="logo" href="{{ route('account.home') }}"><span
class="on_desktop">{{ config('app.name') }}</span></a>
@if (!isset($welcome) || $welcome == false)
<a id="menu" class="on_mobile" href="#"
onclick="document.body.classList.toggle('show_menu')"></a>
@endif
@if (!isset($welcome) || $welcome == false)
<a id="menu" class="on_mobile" href="#"
onclick="document.body.classList.toggle('show_menu')"></a>
@endif
<a class="oppose" href="{{ route('about') }}">
<i class="material-icons-outlined">info</i><span class="on_desktop">About</span>
<a class="oppose" href="{{ route('about') }}">
<i class="material-icons-outlined">info</i><span class="on_desktop">About</span>
</a>
@if (auth()->user())
<a class="oppose" href="{{ route('account.dashboard') }}">
<i class="material-icons-outlined">account_circle</i><span
class="on_desktop">{{ auth()->user()->identifier }}</span>
</a>
@if (auth()->user())
<a class="oppose" href="{{ route('account.dashboard') }}">
<i class="material-icons-outlined">account_circle</i><span
class="on_desktop">{{ auth()->user()->identifier }}</span>
</a>
<a class="oppose" href="{{ route('account.logout') }}">
<i class="material-icons-outlined">logout</i>
</a>
@endif
</nav>
@endif
<a class="oppose" href="{{ route('account.logout') }}">
<i class="material-icons-outlined">logout</i>
</a>
@endif
</nav>
</header>
<content>

View file

@ -1,16 +1,14 @@
@if (config('app.web_panel'))
<p class="text-center pt-3">
@if (config('app.account_email_unique'))
Set or recover your account
@else
Set or recover your password
@endif
using your <a href="{{ route('account.recovery.show.email') }}">Email address</a>
@if (config('app.phone_authentication'))
or your <a href="{{ route('account.recovery.show.phone') }}">Phone number</a>
@endif
</p>
<p class="text-center">
…or login using an already authenticated device <a href="{{ route('account.authenticate.auth_token') }}">by flashing a QRcode</a>.
</p>
@endif
<p class="text-center pt-3">
@if (config('app.account_email_unique'))
Set or recover your account
@else
Set or recover your password
@endif
using your <a href="{{ route('account.recovery.show.email') }}">Email address</a>
@if (config('app.phone_authentication'))
or your <a href="{{ route('account.recovery.show.phone') }}">Phone number</a>
@endif
</p>
<p class="text-center">
…or login using an already authenticated device <a href="{{ route('account.authenticate.auth_token') }}">by flashing a QRcode</a>.
</p>

View file

@ -42,15 +42,15 @@ Route::redirect('/', 'login')->name('account.home');
Route::get('documentation', 'Account\AccountController@documentation')->name('account.documentation');
Route::get('about', 'AboutController@about')->name('about');
if (config('app.web_panel')) {
Route::middleware(['web_panel_enabled'])->group(function () {
Route::get('login', 'Account\AuthenticateController@login')->name('account.login');
Route::post('authenticate', 'Account\AuthenticateController@authenticate')->name('account.authenticate');
Route::get('authenticate/qrcode/{token?}', 'Account\AuthenticateController@loginAuthToken')->name('account.authenticate.auth_token');
}
Route::prefix('creation_token')->controller(CreationRequestTokenController::class)->group(function () {
Route::get('check/{token}', 'check')->name('account.creation_request_token.check');
Route::post('validate', 'validateToken')->name('account.creation_request_token.validate');
Route::prefix('creation_token')->controller(CreationRequestTokenController::class)->group(function () {
Route::get('check/{token}', 'check')->name('account.creation_request_token.check');
Route::post('validate', 'validateToken')->name('account.creation_request_token.validate');
});
});
Route::group(['middleware' => 'auth.digest_or_key'], function () {
@ -69,18 +69,18 @@ Route::name('provisioning.')->prefix('provisioning')->controller(ProvisioningCon
Route::get('/', 'show')->name('show');
});
if (publicRegistrationEnabled()) {
Route::redirect('register', 'register/email')->name('account.register');
Route::middleware(['web_panel_enabled'])->group(function () {
if (config('app.public_registration')) {
Route::redirect('register', 'register/email')->name('account.register');
if (config('app.phone_authentication')) {
Route::get('register/phone', 'Account\RegisterController@registerPhone')->name('account.register.phone');
if (config('app.phone_authentication')) {
Route::get('register/phone', 'Account\RegisterController@registerPhone')->name('account.register.phone');
}
Route::get('register/email', 'Account\RegisterController@registerEmail')->name('account.register.email');
Route::post('accounts', 'Account\AccountController@store')->name('account.store');
}
Route::get('register/email', 'Account\RegisterController@registerEmail')->name('account.register.email');
Route::post('accounts', 'Account\AccountController@store')->name('account.store');
}
if (config('app.web_panel')) {
Route::prefix('recovery')->controller(RecoveryController::class)->group(function () {
Route::get('phone', 'showPhone')->name('account.recovery.show.phone');
Route::get('email', 'showEmail')->name('account.recovery.show.email');
@ -234,4 +234,4 @@ if (config('app.web_panel')) {
});
});
});
}
});

View file

@ -51,6 +51,16 @@ class AccountProvisioningTest extends TestCase
->assertDontSee('ha1');
}
public function testDisabledProvisioningHeader()
{
config()->set('app.provisioning_use_x_linphone_provisioning_header', false);
$this->get($this->route)
->assertStatus(200)
->assertHeader('Content-Type', 'application/xml')
->assertDontSee('ha1');
}
public function testXLinphoneProvisioningHeader()
{
$this->withHeaders([

View file

@ -28,8 +28,6 @@ abstract class TestCase extends BaseTestCase
{
use CreatesApplication;
const ALGORITHMS = ['md5' => 'MD5', 'sha256' => 'SHA-256'];
protected $route = '/api/accounts/me';
protected $method = 'GET';
@ -88,7 +86,7 @@ abstract class TestCase extends BaseTestCase
$extractedChallenge['qop'],
$response,
$extractedChallenge['opaque'],
self::ALGORITHMS[$hash],
array_flip(passwordAlgorithms())[$hash],
);
return 'Digest ' . $digest;