mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-01-18 02:18:06 +00:00
Compare commits
16 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c8b5aebdb | ||
|
|
09ec7ee043 | ||
|
|
ec286ff9a8 | ||
|
|
55a78b3e86 | ||
|
|
53ad79b42e | ||
|
|
5930e78586 | ||
|
|
4f016c70a3 | ||
|
|
5b86cc75c9 | ||
|
|
10a29b7420 | ||
|
|
adbf8320e7 | ||
|
|
07f2048c10 | ||
|
|
3e23ebcc70 | ||
|
|
c770798493 | ||
|
|
4d9a19f8cf | ||
|
|
b70fc27fea | ||
|
|
1c0d069afc |
35 changed files with 455 additions and 268 deletions
|
|
@ -1,7 +1,7 @@
|
|||
variables:
|
||||
ROCKY_8_IMAGE_VERSION: 20230330_163028_remove_remi
|
||||
ROCKY_9_IMAGE_VERSION: 20231019_170719_rocky9_php80_cleanup
|
||||
DEBIAN_11_IMAGE_VERSION: 20230322_172926_missing_tools
|
||||
DEBIAN_11_IMAGE_VERSION: 20240221_140459_package_upgrade_02_24
|
||||
DEBIAN_12_IMAGE_VERSION: 20230925_143235_enable_debian12_packaging
|
||||
PHP_REDIS_REMI_VERSION: php-pecl-redis5-5.3.6-1
|
||||
PHP_IGBINARY_REMI_VERSION: php-pecl-igbinary-3.2.14-1
|
||||
|
|
|
|||
32
CHANGELOG.md
32
CHANGELOG.md
|
|
@ -1,5 +1,37 @@
|
|||
# Flexisip Account Manager Changelog
|
||||
|
||||
v1.5
|
||||
----
|
||||
|
||||
v1.4.7
|
||||
------
|
||||
- Fix FLEXIAPI-175 and FLEXISIP-231 Rewrite the Redis contacts parser to handle properly SIP uris (thanks @thibault.lemaire !)
|
||||
|
||||
v1.4.6
|
||||
------
|
||||
- Fix FLEXIAPI-142 PUT /accounts endpoint doesn't allow overiding values anymore
|
||||
- Fix typos and dependencies
|
||||
|
||||
v1.4.5
|
||||
------
|
||||
- Fix FLEXIAPI-132 Refactor the Provisioning to remove proxy_default_values
|
||||
|
||||
v1.4.4
|
||||
------
|
||||
- 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
|
||||
|
|
|
|||
12
README.md
12
README.md
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -46,6 +48,7 @@ INTERCOM_FEATURES=false # Toggle to enable/disable the intercom related features
|
|||
|
||||
TERMS_OF_USE_URL= # A URL pointing to the Terms of Use
|
||||
PRIVACY_POLICY_URL= # A URL pointing to the Privacy Policy
|
||||
APP_PROJECT_URL= # A URL pointing to the project information page
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
|
||||
|
|
@ -101,4 +104,4 @@ OVH_APP_SENDER=
|
|||
|
||||
# Google reCaptcha v2 parameters
|
||||
NOCAPTCHA_SECRET=secret-key
|
||||
NOCAPTCHA_SITEKEY=site-key
|
||||
NOCAPTCHA_SITEKEY=site-key
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -373,8 +367,8 @@ IMPP:sip:' . $this->getIdentifierAttribute();
|
|||
|
||||
$vcard .= '
|
||||
FN:';
|
||||
$vcard .= !empty($this->attributes['display_name'])
|
||||
? $this->attributes['display_name']
|
||||
$vcard .= !empty($this->display_name)
|
||||
? $this->display_name
|
||||
: $this->getIdentifierAttribute();
|
||||
|
||||
if ($this->dtmf_protocol) {
|
||||
|
|
|
|||
|
|
@ -26,25 +26,16 @@ class Device extends Model
|
|||
{
|
||||
public function fromRedisContact(string $contact)
|
||||
{
|
||||
// Ugly :'(
|
||||
$result = [];
|
||||
$exploded = explode(';', urldecode($contact));
|
||||
preg_match("/<(.*)>;(.*)/", $contact, $matches);
|
||||
|
||||
foreach ($exploded as $line) {
|
||||
$line = explode('=', $line);
|
||||
$parsed = parse_url($matches[1]);
|
||||
parse_str($parsed["query"], $query);
|
||||
|
||||
if (count($line) == 2) {
|
||||
$result[trim($line[0])] = $line[1];
|
||||
}
|
||||
parse_str(str_replace(";", "&", $parsed["path"]), $sipParams);
|
||||
parse_str(str_replace(";", "&", $matches[2]), $sipHeaders);
|
||||
|
||||
// User agent
|
||||
if (count($line) == 4) {
|
||||
$result['userAgent'] = substr($line[3], 0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
$this->uuid = \substr($result['sip.instance'], 2, -2);
|
||||
$this->update_time = Carbon::createFromTimestamp($result['updatedAt']);
|
||||
$this->user_agent = $result['userAgent'];
|
||||
$this->uuid = substr($sipHeaders['sip_instance'], 2, -2);
|
||||
$this->update_time = Carbon::createFromTimestamp($sipParams['updatedAt']);
|
||||
$this->user_agent = $query["user-agent"];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 () {
|
||||
|
|
@ -119,7 +120,7 @@ function captchaConfigured(): bool
|
|||
|
||||
function resolveUserContacts(Request $request)
|
||||
{
|
||||
$selected = ['id', 'username', 'domain', 'activated', 'dtmf_protocol'];
|
||||
$selected = ['id', 'username', 'domain', 'activated', 'dtmf_protocol', 'display_name'];
|
||||
|
||||
return Account::whereIn('id', function ($query) use ($request) {
|
||||
$query->select('contact_id')
|
||||
|
|
|
|||
|
|
@ -80,6 +80,29 @@ class AuthenticateController extends Controller
|
|||
return redirect()->back()->withErrors(['authentication' => 'Wrong username or password']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated
|
||||
*/
|
||||
public function validateEmail(Request $request, string $code)
|
||||
{
|
||||
$request->merge(['code' => $code]);
|
||||
$request->validate(['code' => 'required|size:' . self::$emailCodeSize]);
|
||||
|
||||
$account = Account::where('confirmation_key', $code)->first();
|
||||
|
||||
if (!$account) {
|
||||
return redirect()->route('account.login');
|
||||
}
|
||||
|
||||
$account->confirmation_key = null;
|
||||
$account->activated = true;
|
||||
$account->save();
|
||||
|
||||
Auth::login($account);
|
||||
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
|
||||
public function loginAuthToken(Request $request, ?string $token = null)
|
||||
{
|
||||
$authToken = null;
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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'));
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class Authenticate extends Middleware
|
|||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
if (!$request->expectsJson()) {
|
||||
return route('account.home');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
42
flexiapi/app/Http/Middleware/IsWebPanelEnabled.php
Normal file
42
flexiapi/app/Http/Middleware/IsWebPanelEnabled.php
Normal 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');
|
||||
}
|
||||
}
|
||||
|
|
@ -30,23 +30,22 @@ class UpdateAccountRequest extends FormRequest
|
|||
new SIPUsername,
|
||||
Rule::unique('accounts', 'username')->where(function ($query) {
|
||||
$query->where('domain', resolveDomain($this));
|
||||
})->ignore($this->route('account_id'), 'id'),
|
||||
})->ignore($this->route('id'), 'id'),
|
||||
'filled',
|
||||
],
|
||||
'email' => [
|
||||
'nullable',
|
||||
'email',
|
||||
config('app.account_email_unique') ? Rule::unique('accounts', 'email')->ignore($this->route('account_id')) : null
|
||||
config('app.account_email_unique') ? Rule::unique('accounts', 'email')->ignore($this->route('id')) : null
|
||||
],
|
||||
'role' => 'in:admin,end_user',
|
||||
'password_sha256' => 'nullable|min:3',
|
||||
'dtmf_protocol' => 'nullable|in:' . Account::dtmfProtocolsRule(),
|
||||
'phone' => [
|
||||
'nullable',
|
||||
Rule::unique('accounts', 'username')->where(function ($query) {
|
||||
$query->where('domain', resolveDomain($this));
|
||||
})->ignore($this->route('account_id'), 'id'),
|
||||
Rule::unique('aliases', 'alias')->ignore($this->route('account_id'), 'account_id'),
|
||||
})->ignore($this->route('id'), 'id'),
|
||||
Rule::unique('aliases', 'alias')->ignore($this->route('id'), 'account_id'),
|
||||
new WithoutSpaces, 'starts_with:+'
|
||||
]
|
||||
];
|
||||
|
|
|
|||
18
flexiapi/app/Rules/PasswordAlgorithm.php
Normal file
18
flexiapi/app/Rules/PasswordAlgorithm.php
Normal 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()));
|
||||
}
|
||||
}
|
||||
|
|
@ -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
279
flexiapi/composer.lock
generated
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -13,9 +13,10 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'name' => env('APP_NAME', 'Laravel'),
|
||||
'name' => env('APP_NAME', 'Account Manager'),
|
||||
'sip_domain' => env('APP_SIP_DOMAIN', 'sip.domain.com'),
|
||||
|
||||
'project_url' => env('APP_PROJECT_URL', ''),
|
||||
'terms_of_use_url' => env('TERMS_OF_USE_URL', ''),
|
||||
'privacy_policy_url' => env('PRIVACY_POLICY_URL', ''),
|
||||
|
||||
|
|
@ -32,6 +33,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 +57,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
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class AccountFactory extends Factory
|
|||
{
|
||||
return [
|
||||
'username' => $this->faker->username,
|
||||
'display_name' => $this->faker->username,
|
||||
'display_name' => $this->faker->name,
|
||||
'domain' => config('app.sip_domain'),
|
||||
'email' => $this->faker->email,
|
||||
'user_agent' => $this->faker->userAgent,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@
|
|||
<h2>About</h2>
|
||||
<hr />
|
||||
|
||||
<p><a href="https://linphone.org/">https://linphone.org</a></p>
|
||||
@if (!empty(config('app.project_url')))
|
||||
<p><a href="{{ config('app.project_url') }}">{{ config('app.project_url') }}</a></p>
|
||||
@endif
|
||||
|
||||
<p><a href="{{ config('app.terms_of_use_url') }}">Terms and Conditions</a> and <a
|
||||
href="{{ config('app.privacy_policy_url') }}">Privacy policy</a></p>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
<input name="account_creation_request_token" type="hidden" value="{{ $account_creation_request_token->token }}">
|
||||
@include('parts.captcha')
|
||||
<input class="btn btn-primary" type="submit" value="I\'m not a robot">
|
||||
<input class="btn btn-primary" type="submit" value="I'm not a robot">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@endsection
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
@include('parts.recovery')
|
||||
|
||||
@if (publicRegistrationEnabled())
|
||||
@if (config('app.public_registration'))
|
||||
<br />
|
||||
<br />
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -42,15 +42,18 @@ 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');
|
||||
// Deprecated
|
||||
Route::get('authenticate/email/{code}', 'Account\AuthenticateController@validateEmail')->name('account.authenticate.email_confirm');
|
||||
|
||||
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 +72,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 +237,4 @@ if (config('app.web_panel')) {
|
|||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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([
|
||||
|
|
@ -92,6 +102,8 @@ class AccountProvisioningTest extends TestCase
|
|||
public function testAuthenticatedReProvisioning()
|
||||
{
|
||||
$password = Password::factory()->create();
|
||||
$password->account->display_name = "Anna O'Reily";
|
||||
$password->account->save();
|
||||
$password->account->generateApiKey();
|
||||
|
||||
$provisioningToken = $password->account->provisioning_token;
|
||||
|
|
@ -116,7 +128,7 @@ class AccountProvisioningTest extends TestCase
|
|||
->assertStatus(200)
|
||||
->assertHeader('Content-Type', 'application/xml')
|
||||
->assertSee($password->account->username)
|
||||
->assertSee($password->account->display_name)
|
||||
->assertSee($password->account->display_name, false)
|
||||
->assertSee('ha1');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -578,6 +578,7 @@ class ApiAccountTest extends TestCase
|
|||
$username = 'changed';
|
||||
$algorithm = 'MD5';
|
||||
$password = 'other';
|
||||
$newDisplayName = 'new_display_name';
|
||||
|
||||
$this->keyAuthenticated($admin->account)
|
||||
->json('PUT', $this->route . '/1234')
|
||||
|
|
@ -590,6 +591,15 @@ class ApiAccountTest extends TestCase
|
|||
])
|
||||
->assertStatus(422);
|
||||
|
||||
$this->keyAuthenticated($admin->account)
|
||||
->json('PUT', $this->route . '/' . $account->id, [
|
||||
'username' => $username,
|
||||
'algorithm' => $algorithm,
|
||||
'password' => $password,
|
||||
'display_name' => $newDisplayName
|
||||
])
|
||||
->assertStatus(200);
|
||||
|
||||
$this->keyAuthenticated($admin->account)
|
||||
->json('PUT', $this->route . '/' . $account->id, [
|
||||
'username' => $username,
|
||||
|
|
@ -600,7 +610,8 @@ class ApiAccountTest extends TestCase
|
|||
|
||||
$this->assertDatabaseHas('accounts', [
|
||||
'id' => $account->id,
|
||||
'username' => $username
|
||||
'username' => $username,
|
||||
'display_name' => null
|
||||
]);
|
||||
|
||||
$this->assertDatabaseHas('passwords', [
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue