diff --git a/flexiapi/app/Account.php b/flexiapi/app/Account.php index b480df8..3950422 100644 --- a/flexiapi/app/Account.php +++ b/flexiapi/app/Account.php @@ -39,9 +39,10 @@ class Account extends Authenticatable use HasFactory; protected $connection = 'external'; - protected $with = ['passwords', 'admin', 'emailChanged']; + protected $with = ['passwords', 'admin', 'emailChanged', 'alias']; + protected $hidden = ['alias', 'expire_time', 'confirmation_key']; protected $dateTimes = ['creation_time']; - protected $appends = ['realm']; + protected $appends = ['realm', 'phone']; protected $casts = [ 'activated' => 'boolean', ]; @@ -72,6 +73,11 @@ class Account extends Authenticatable return $query->where('id', '<', 0); } + public function phoneChangeCode() + { + return $this->hasOne('App\PhoneChangeCode'); + } + public function passwords() { return $this->hasMany('App\Password'); @@ -112,6 +118,20 @@ class Account extends Authenticatable return config('app.realm'); } + public function getResolvedRealmAttribute() + { + return config('app.realm') ?? $this->domain; + } + + public function getPhoneAttribute() + { + if ($this->alias) { + return $this->alias->alias; + } + + return null; + } + public function requestEmailUpdate(string $newEmail) { // Remove all the old requests @@ -150,7 +170,7 @@ class Account extends Authenticatable $password = new Password; $password->account_id = $this->id; - $password->password = Utils::bchash($this->username, $this->domain, $newPassword, $algorithm); + $password->password = Utils::bchash($this->username, $this->resolvedRealm, $newPassword, $algorithm); $password->algorithm = $algorithm; $password->save(); } diff --git a/flexiapi/app/Http/Controllers/Account/PasswordController.php b/flexiapi/app/Http/Controllers/Account/PasswordController.php index b3d1c2c..f032cf4 100644 --- a/flexiapi/app/Http/Controllers/Account/PasswordController.php +++ b/flexiapi/app/Http/Controllers/Account/PasswordController.php @@ -23,8 +23,6 @@ use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Mail; -use App\Account; -use App\Password; use App\Helpers\Utils; use App\Mail\ConfirmedRegistration; @@ -56,7 +54,7 @@ class PasswordController extends Controller // If one of the password stored equals the one entered if (hash_equals( $password->password, - Utils::bchash($account->username, $account->domain, $request->get('old_password'), $password->algorithm) + Utils::bchash($account->username, $account->resolvedRealm, $request->get('old_password'), $password->algorithm) )) { $account->updatePassword($request->get('password'), $algorithm); $request->session()->flash('success', 'Password successfully changed'); diff --git a/flexiapi/app/Http/Controllers/Account/RegisterController.php b/flexiapi/app/Http/Controllers/Account/RegisterController.php index 4e5244e..9c38558 100644 --- a/flexiapi/app/Http/Controllers/Account/RegisterController.php +++ b/flexiapi/app/Http/Controllers/Account/RegisterController.php @@ -28,7 +28,6 @@ use Carbon\Carbon; use App\Account; use App\Alias; -use App\Rules\SIP; use App\Rules\WithoutSpaces; use App\Helpers\Utils; use App\Libraries\OvhSMS; diff --git a/flexiapi/app/Http/Controllers/Api/AccountPhoneController.php b/flexiapi/app/Http/Controllers/Api/AccountPhoneController.php new file mode 100644 index 0000000..d046fc5 --- /dev/null +++ b/flexiapi/app/Http/Controllers/Api/AccountPhoneController.php @@ -0,0 +1,84 @@ +. +*/ + +namespace App\Http\Controllers\Api; + +use Illuminate\Http\Request; +use App\Http\Controllers\Controller; + +use App\Rules\WithoutSpaces; +use App\Helpers\Utils; +use App\Libraries\OvhSMS; + +use App\PhoneChangeCode; +use App\Alias; + +class AccountPhoneController extends Controller +{ + public function requestUpdate(Request $request) + { + $request->validate([ + 'phone' => [ + 'required', 'unique:external.aliases,alias', + 'unique:external.accounts,username', + new WithoutSpaces, 'starts_with:+', 'phone:AUTO' + ] + ]); + + $account = $request->user(); + + $phoneChangeCode = $account->phoneChangeCode ?? new PhoneChangeCode; + $phoneChangeCode->account_id = $account->id; + $phoneChangeCode->phone = $request->get('phone'); + $phoneChangeCode->code = Utils::generatePin(); + $phoneChangeCode->save(); + + $ovhSMS = new OvhSMS; + $ovhSMS->send($request->get('phone'), 'Your ' . config('app.name') . ' validation code is ' . $phoneChangeCode->code); + } + + public function update(Request $request) + { + $request->validate([ + 'code' => 'required|digits:4' + ]); + + $account = $request->user(); + + $phoneChangeCode = $account->phoneChangeCode()->firstOrFail(); + if ($phoneChangeCode->code == $request->get('code')) { + $account->alias()->delete(); + + $alias = new Alias; + $alias->alias = $phoneChangeCode->phone; + $alias->domain = config('app.sip_domain'); + $alias->account_id = $account->id; + $alias->save(); + + $phoneChangeCode->delete(); + + $account->refresh(); + + return $account; + } + + $phoneChangeCode->delete(); + abort(403); + } +} diff --git a/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php b/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php index b7f2b11..831b0b9 100644 --- a/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php +++ b/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php @@ -107,7 +107,7 @@ class AccountController extends Controller $password = new Password; $password->account_id = $account->id; - $password->password = Utils::bchash($account->username, $account->domain, $request->get('password'), $request->get('algorithm')); + $password->password = Utils::bchash($account->username, $account->resolvedRealm, $request->get('password'), $request->get('algorithm')); $password->algorithm = $request->get('algorithm'); $password->save(); diff --git a/flexiapi/app/Http/Controllers/Api/PasswordController.php b/flexiapi/app/Http/Controllers/Api/PasswordController.php index d9132e8..637d3b1 100644 --- a/flexiapi/app/Http/Controllers/Api/PasswordController.php +++ b/flexiapi/app/Http/Controllers/Api/PasswordController.php @@ -30,7 +30,7 @@ class PasswordController extends Controller foreach ($account->passwords as $password) { if (hash_equals( $password->password, - Utils::bchash($account->username, $account->domain, $request->get('old_password'), $password->algorithm) + Utils::bchash($account->username, $account->resolvedRealm, $request->get('old_password'), $password->algorithm) )) { $account->updatePassword($request->get('password'), $algorithm); return response()->json(); diff --git a/flexiapi/app/Http/Middleware/AuthenticateDigestOrKey.php b/flexiapi/app/Http/Middleware/AuthenticateDigestOrKey.php index c24bd81..e6e7ffc 100644 --- a/flexiapi/app/Http/Middleware/AuthenticateDigestOrKey.php +++ b/flexiapi/app/Http/Middleware/AuthenticateDigestOrKey.php @@ -22,7 +22,6 @@ namespace App\Http\Middleware; use App\Account; use App\Helpers\Utils; -use Fabiang\Sasl\Sasl; use Illuminate\Validation\Rule; use Illuminate\Support\Facades\Auth; use Illuminate\Http\Response; @@ -45,7 +44,7 @@ class AuthenticateDigestOrKey */ public function handle($request, Closure $next) { - $validator = Validator::make(['from' => $request->header('From')], [ + Validator::make(['from' => $request->header('From')], [ 'from' => 'required', ])->validate(); @@ -95,7 +94,7 @@ class AuthenticateDigestOrKey $storedNonce->save(); // Validation - $validator = Validator::make($auth, [ + Validator::make($auth, [ 'opaque' => 'required|in:'.$this->getOpaque(), //'uri' => 'in:/'.$request->path(), 'qop' => 'required|in:auth', diff --git a/flexiapi/app/Libraries/OvhSMS.php b/flexiapi/app/Libraries/OvhSMS.php index 08a6e9b..754ebc1 100644 --- a/flexiapi/app/Libraries/OvhSMS.php +++ b/flexiapi/app/Libraries/OvhSMS.php @@ -19,7 +19,6 @@ namespace App\Libraries; -use App\Device; use Ovh\Api; class OvhSMS @@ -55,9 +54,9 @@ class OvhSMS 'validityPeriod' => 2880 ]; - $resultPostJob = $this->_api->post('/sms/'. $this->_smsService . '/jobs', $content); + $this->_api->post('/sms/'. $this->_smsService . '/jobs', $content); // One credit removed - $smsJobs = $this->_api->get('/sms/'. $this->_smsService . '/jobs'); + $this->_api->get('/sms/'. $this->_smsService . '/jobs'); } } \ No newline at end of file diff --git a/flexiapi/app/PhoneChangeCode.php b/flexiapi/app/PhoneChangeCode.php new file mode 100644 index 0000000..57df589 --- /dev/null +++ b/flexiapi/app/PhoneChangeCode.php @@ -0,0 +1,18 @@ +belongsTo('App\Account'); + } +} diff --git a/flexiapi/composer.phar b/flexiapi/composer.phar new file mode 100755 index 0000000..9efd41a Binary files /dev/null and b/flexiapi/composer.phar differ diff --git a/flexiapi/database/factories/AccountFactory.php b/flexiapi/database/factories/AccountFactory.php index 86b6459..f63f0ba 100644 --- a/flexiapi/database/factories/AccountFactory.php +++ b/flexiapi/database/factories/AccountFactory.php @@ -21,7 +21,6 @@ namespace Database\Factories; use App\Account; use Illuminate\Database\Eloquent\Factories\Factory; -use Illuminate\Support\Str; class AccountFactory extends Factory { diff --git a/flexiapi/database/factories/PasswordFactory.php b/flexiapi/database/factories/PasswordFactory.php index 911ead0..842c7a2 100644 --- a/flexiapi/database/factories/PasswordFactory.php +++ b/flexiapi/database/factories/PasswordFactory.php @@ -21,10 +21,7 @@ namespace Database\Factories; use App\Account; use App\Password; -use App\User; use Illuminate\Database\Eloquent\Factories\Factory; -use Illuminate\Support\Str; -use Illuminate\Support\Facades\DB; class PasswordFactory extends Factory { diff --git a/flexiapi/database/factories/PhoneChangeCodeFactory.php b/flexiapi/database/factories/PhoneChangeCodeFactory.php new file mode 100644 index 0000000..bde9eff --- /dev/null +++ b/flexiapi/database/factories/PhoneChangeCodeFactory.php @@ -0,0 +1,42 @@ +. +*/ + +namespace Database\Factories; + +use App\Helpers\Utils; +use App\Password; +use App\PhoneChangeCode; +use Illuminate\Database\Eloquent\Factories\Factory; + +class PhoneChangeCodeFactory extends Factory +{ + protected $model = PhoneChangeCode::class; + + public function definition() + { + $password = Password::factory()->create(); + $password->account->generateApiKey(); + + return [ + 'account_id' => $password->account->id, + 'code' => Utils::generatePin(), + 'phone' => '+3312341234', + ]; + } +} \ No newline at end of file diff --git a/flexiapi/database/migrations/2021_02_10_160119_add_phone_change_codes_table.php b/flexiapi/database/migrations/2021_02_10_160119_add_phone_change_codes_table.php new file mode 100644 index 0000000..0be2a57 --- /dev/null +++ b/flexiapi/database/migrations/2021_02_10_160119_add_phone_change_codes_table.php @@ -0,0 +1,24 @@ +create('phone_change_codes', function (Blueprint $table) { + $table->bigIncrements('id'); + $table->integer('account_id')->unsigned(); + $table->string('code'); + $table->string('phone'); + $table->timestamps(); + }); + } + + public function down() + { + Schema::connection('local')->dropIfExists('phone_change_codes'); + } +} diff --git a/flexiapi/resources/views/documentation.blade.php b/flexiapi/resources/views/documentation.blade.php index e26f527..880bc67 100644 --- a/flexiapi/resources/views/documentation.blade.php +++ b/flexiapi/resources/views/documentation.blade.php @@ -100,6 +100,24 @@ For the moment only DIGEST-MD5 and DIGEST-SHA-256 are supported through the auth
password required, the new passwordPOST /accounts/me/phone/requestRequest a specific code by SMS
+JSON parameters:
+phone the phone number to send the SMSPOST /accounts/me/phoneConfirm the code received and change the phone number
+JSON parameters:
+code the received SMS codeReturn the updated account
+GET /accounts/me/devices