diff --git a/flexiapi/app/Account.php b/flexiapi/app/Account.php
index c5d456a..ccf1e4f 100644
--- a/flexiapi/app/Account.php
+++ b/flexiapi/app/Account.php
@@ -108,62 +108,62 @@ class Account extends Authenticatable
public function activationExpiration()
{
- return $this->hasOne('App\ActivationExpiration');
+ return $this->hasOne(ActivationExpiration::class);
}
public function admin()
{
- return $this->hasOne('App\Admin');
+ return $this->hasOne(Admin::class);
}
public function alias()
{
- return $this->hasOne('App\Alias');
+ return $this->hasOne(Alias::class);
}
public function apiKey()
{
- return $this->hasOne('App\ApiKey');
+ return $this->hasOne(ApiKey::class);
}
public function externalAccount()
{
- return $this->hasOne('App\ExternalAccount');
+ return $this->hasOne(ExternalAccount::class);
}
public function contacts()
{
- return $this->belongsToMany('App\Account', 'contacts', 'account_id', 'contact_id');
+ return $this->belongsToMany(Account::class, 'contacts', 'account_id', 'contact_id');
}
public function emailChanged()
{
- return $this->hasOne('App\EmailChanged');
+ return $this->hasOne(EmailChanged::class);
}
public function nonces()
{
- return $this->hasMany('App\DigestNonce');
+ return $this->hasMany(DigestNonce::class);
}
public function authTokens()
{
- return $this->hasMany('App\AuthToken');
+ return $this->hasMany(AuthToken::class);
}
public function passwords()
{
- return $this->hasMany('App\Password');
+ return $this->hasMany(Password::class);
}
public function phoneChangeCode()
{
- return $this->hasOne('App\PhoneChangeCode');
+ return $this->hasOne(PhoneChangeCode::class);
}
public function types()
{
- return $this->belongsToMany('App\AccountType');
+ return $this->belongsToMany(AccountType::class);
}
/**
diff --git a/flexiapi/app/AccountAction.php b/flexiapi/app/AccountAction.php
index 3e70055..7851dd3 100644
--- a/flexiapi/app/AccountAction.php
+++ b/flexiapi/app/AccountAction.php
@@ -30,6 +30,6 @@ class AccountAction extends Model
public function account()
{
- return $this->belongsTo('App\Account');
+ return $this->belongsTo(Account::class);
}
}
diff --git a/flexiapi/app/AccountCreationRequestToken.php b/flexiapi/app/AccountCreationRequestToken.php
new file mode 100644
index 0000000..ddf51e8
--- /dev/null
+++ b/flexiapi/app/AccountCreationRequestToken.php
@@ -0,0 +1,35 @@
+.
+*/
+
+namespace App;
+
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class AccountCreationRequestToken extends Model
+{
+ use HasFactory;
+
+ protected $hidden = ['id', 'updated_at', 'created_at'];
+
+ public function accountCreationToken()
+ {
+ return $this->belongsTo(AccountCreationToken::class, 'acc_creation_token_id');
+ }
+}
diff --git a/flexiapi/app/AccountCreationToken.php b/flexiapi/app/AccountCreationToken.php
index 3f3d458..754224a 100644
--- a/flexiapi/app/AccountCreationToken.php
+++ b/flexiapi/app/AccountCreationToken.php
@@ -25,4 +25,11 @@ use Illuminate\Database\Eloquent\Model;
class AccountCreationToken extends Model
{
use HasFactory;
+
+ protected $hidden = ['id', 'updated_at', 'created_at'];
+
+ public function accountCreationRequestToken()
+ {
+ return $this->hasOne(AccountCreationRequestToken::class, 'acc_creation_token_id');
+ }
}
diff --git a/flexiapi/app/AccountType.php b/flexiapi/app/AccountType.php
index f85408b..2592b3d 100644
--- a/flexiapi/app/AccountType.php
+++ b/flexiapi/app/AccountType.php
@@ -30,6 +30,6 @@ class AccountType extends Model
public function accounts()
{
- return $this->belongsToMany('App\Account');
+ return $this->belongsToMany(Account::class);
}
}
diff --git a/flexiapi/app/ActivationExpiration.php b/flexiapi/app/ActivationExpiration.php
index 4ec9a27..362ed98 100644
--- a/flexiapi/app/ActivationExpiration.php
+++ b/flexiapi/app/ActivationExpiration.php
@@ -33,7 +33,7 @@ class ActivationExpiration extends Model
public function account()
{
- return $this->belongsTo('App\Account');
+ return $this->belongsTo(Account::class);
}
public function isExpired()
diff --git a/flexiapi/app/Http/Controllers/Account/CreationRequestTokenController.php b/flexiapi/app/Http/Controllers/Account/CreationRequestTokenController.php
new file mode 100644
index 0000000..449b37d
--- /dev/null
+++ b/flexiapi/app/Http/Controllers/Account/CreationRequestTokenController.php
@@ -0,0 +1,46 @@
+merge(['account_creation_request_token' => $creationRequestToken]);
+ $request->validate([
+ 'account_creation_request_token' => [
+ 'required',
+ new RulesAccountCreationRequestToken
+ ]
+ ]);
+
+ $accountCreationRequestToken = AccountCreationRequestToken::where('token', $request->get('account_creation_request_token'))->firstOrFail();
+
+ return view('account.creation_request_token.check', [
+ 'account_creation_request_token' => $accountCreationRequestToken
+ ]);
+ }
+
+ public function validateToken(Request $request)
+ {
+ $request->validate([
+ 'account_creation_request_token' => [
+ 'required',
+ new RulesAccountCreationRequestToken
+ ],
+ 'g-recaptcha-response' => 'required|captcha',
+ ]);
+
+ $accountCreationRequestToken = AccountCreationRequestToken::where('token', $request->get('account_creation_request_token'))->firstOrFail();
+ $accountCreationRequestToken->validated_at = Carbon::now();
+ $accountCreationRequestToken->save();
+
+ return view('account.creation_request_token.valid');
+ }
+}
diff --git a/flexiapi/app/Http/Controllers/Api/AccountController.php b/flexiapi/app/Http/Controllers/Api/Account/AccountController.php
similarity index 97%
rename from flexiapi/app/Http/Controllers/Api/AccountController.php
rename to flexiapi/app/Http/Controllers/Api/Account/AccountController.php
index ce2c0a7..4751361 100644
--- a/flexiapi/app/Http/Controllers/Api/AccountController.php
+++ b/flexiapi/app/Http/Controllers/Api/Account/AccountController.php
@@ -17,7 +17,7 @@
along with this program. If not, see .
*/
-namespace App\Http\Controllers\Api;
+namespace App\Http\Controllers\Api\Account;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
@@ -253,20 +253,15 @@ class AccountController extends Controller
'password' => 'required|filled',
'dtmf_protocol' => 'nullable|in:' . Account::dtmfProtocolsRule(),
'account_creation_token' => [
- 'required_without:token',
+ 'required',
new RulesAccountCreationToken
],
'email' => config('app.account_email_unique')
? 'nullable|email|unique:accounts,email'
: 'nullable|email',
- // For retro-compatibility
- 'token' => [
- 'required_without:account_creation_token',
- new RulesAccountCreationToken
- ],
]);
- $token = AccountCreationToken::where('token', $request->get('token') ?? $request->get('account_creation_token'))->first();
+ $token = AccountCreationToken::where('token', $request->get('account_creation_token'))->first();
$token->used = true;
$token->save();
diff --git a/flexiapi/app/Http/Controllers/Api/ApiKeyController.php b/flexiapi/app/Http/Controllers/Api/Account/ApiKeyController.php
similarity index 96%
rename from flexiapi/app/Http/Controllers/Api/ApiKeyController.php
rename to flexiapi/app/Http/Controllers/Api/Account/ApiKeyController.php
index 324f5a3..7d121f9 100644
--- a/flexiapi/app/Http/Controllers/Api/ApiKeyController.php
+++ b/flexiapi/app/Http/Controllers/Api/Account/ApiKeyController.php
@@ -1,6 +1,6 @@
.
*/
-namespace App\Http\Controllers\Api;
+namespace App\Http\Controllers\Api\Account;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
-class AccountContactController extends Controller
+class ContactController extends Controller
{
private $selected = ['id', 'username', 'domain', 'activated', 'dtmf_protocol'];
diff --git a/flexiapi/app/Http/Controllers/Api/Account/CreationRequestToken.php b/flexiapi/app/Http/Controllers/Api/Account/CreationRequestToken.php
new file mode 100644
index 0000000..f346748
--- /dev/null
+++ b/flexiapi/app/Http/Controllers/Api/Account/CreationRequestToken.php
@@ -0,0 +1,21 @@
+token = Str::random(WebAuthenticateController::$emailCodeSize);
+ $creationRequestToken->save();
+
+ return $creationRequestToken;
+ }
+}
diff --git a/flexiapi/app/Http/Controllers/Api/AccountCreationTokenController.php b/flexiapi/app/Http/Controllers/Api/Account/CreationTokenController.php
similarity index 62%
rename from flexiapi/app/Http/Controllers/Api/AccountCreationTokenController.php
rename to flexiapi/app/Http/Controllers/Api/Account/CreationTokenController.php
index 3944886..3cc3eb9 100644
--- a/flexiapi/app/Http/Controllers/Api/AccountCreationTokenController.php
+++ b/flexiapi/app/Http/Controllers/Api/Account/CreationTokenController.php
@@ -17,8 +17,9 @@
along with this program. If not, see .
*/
-namespace App\Http\Controllers\Api;
+namespace App\Http\Controllers\Api\Account;
+use App\AccountCreationRequestToken;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
@@ -27,8 +28,9 @@ use Illuminate\Support\Facades\Log;
use App\AccountCreationToken;
use App\Libraries\FlexisipPusherConnector;
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
+use App\Rules\AccountCreationRequestToken as RulesAccountCreationRequestToken;
-class AccountCreationTokenController extends Controller
+class CreationTokenController extends Controller
{
public function sendByPush(Request $request)
{
@@ -55,4 +57,32 @@ class AccountCreationTokenController extends Controller
abort(503, "Token not sent");
}
+
+ public function usingAccountRequestToken(Request $request)
+ {
+ $request->validate([
+ 'account_creation_request_token' => [
+ 'required',
+ new RulesAccountCreationRequestToken
+ ]
+ ]);
+
+ $creationRequestToken = AccountCreationRequestToken::where('token', $request->get('account_creation_request_token'))
+ ->where('used', false)
+ ->first();
+
+ if ($creationRequestToken && $creationRequestToken->validated_at != null) {
+ $accountCreationToken = new AccountCreationToken;
+ $accountCreationToken->token = Str::random(WebAuthenticateController::$emailCodeSize);
+ $accountCreationToken->save();
+
+ $creationRequestToken->used = true;
+ $creationRequestToken->acc_creation_token_id = $accountCreationToken->id;
+ $creationRequestToken->save();
+
+ return $accountCreationToken;
+ }
+
+ return abort(403);
+ }
}
diff --git a/flexiapi/app/Http/Controllers/Api/DeviceController.php b/flexiapi/app/Http/Controllers/Api/Account/DeviceController.php
similarity index 96%
rename from flexiapi/app/Http/Controllers/Api/DeviceController.php
rename to flexiapi/app/Http/Controllers/Api/Account/DeviceController.php
index 644c987..27450d3 100644
--- a/flexiapi/app/Http/Controllers/Api/DeviceController.php
+++ b/flexiapi/app/Http/Controllers/Api/Account/DeviceController.php
@@ -17,7 +17,7 @@
along with this program. If not, see .
*/
-namespace App\Http\Controllers\Api;
+namespace App\Http\Controllers\Api\Account;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
diff --git a/flexiapi/app/Http/Controllers/Api/EmailController.php b/flexiapi/app/Http/Controllers/Api/Account/EmailController.php
similarity index 96%
rename from flexiapi/app/Http/Controllers/Api/EmailController.php
rename to flexiapi/app/Http/Controllers/Api/Account/EmailController.php
index bb664b9..e5ee106 100644
--- a/flexiapi/app/Http/Controllers/Api/EmailController.php
+++ b/flexiapi/app/Http/Controllers/Api/Account/EmailController.php
@@ -17,7 +17,7 @@
along with this program. If not, see .
*/
-namespace App\Http\Controllers\Api;
+namespace App\Http\Controllers\Api\Account;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
diff --git a/flexiapi/app/Http/Controllers/Api/PasswordController.php b/flexiapi/app/Http/Controllers/Api/Account/PasswordController.php
similarity index 98%
rename from flexiapi/app/Http/Controllers/Api/PasswordController.php
rename to flexiapi/app/Http/Controllers/Api/Account/PasswordController.php
index 58dabe6..103205d 100644
--- a/flexiapi/app/Http/Controllers/Api/PasswordController.php
+++ b/flexiapi/app/Http/Controllers/Api/Account/PasswordController.php
@@ -17,7 +17,7 @@
along with this program. If not, see .
*/
-namespace App\Http\Controllers\Api;
+namespace App\Http\Controllers\Api\Account;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
diff --git a/flexiapi/app/Http/Controllers/Api/AccountPhoneController.php b/flexiapi/app/Http/Controllers/Api/Account/PhoneController.php
similarity index 97%
rename from flexiapi/app/Http/Controllers/Api/AccountPhoneController.php
rename to flexiapi/app/Http/Controllers/Api/Account/PhoneController.php
index b790af9..5655c2c 100644
--- a/flexiapi/app/Http/Controllers/Api/AccountPhoneController.php
+++ b/flexiapi/app/Http/Controllers/Api/Account/PhoneController.php
@@ -17,7 +17,7 @@
along with this program. If not, see .
*/
-namespace App\Http\Controllers\Api;
+namespace App\Http\Controllers\Api\Account;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
@@ -29,7 +29,7 @@ use App\Libraries\OvhSMS;
use App\PhoneChangeCode;
use App\Alias;
-class AccountPhoneController extends Controller
+class PhoneController extends Controller
{
public function requestUpdate(Request $request)
{
diff --git a/flexiapi/app/Http/Controllers/Api/Admin/AccountCreationTokenController.php b/flexiapi/app/Http/Controllers/Api/Admin/AccountCreationTokenController.php
index 16e7d95..bbdc76e 100644
--- a/flexiapi/app/Http/Controllers/Api/Admin/AccountCreationTokenController.php
+++ b/flexiapi/app/Http/Controllers/Api/Admin/AccountCreationTokenController.php
@@ -17,7 +17,7 @@
along with this program. If not, see .
*/
-namespace App\Http\Controllers\Api;
+namespace App\Http\Controllers\Api\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
diff --git a/flexiapi/app/Http/Controllers/Api/MessageController.php b/flexiapi/app/Http/Controllers/Api/Admin/MessageController.php
similarity index 97%
rename from flexiapi/app/Http/Controllers/Api/MessageController.php
rename to flexiapi/app/Http/Controllers/Api/Admin/MessageController.php
index 2f66724..fbeaa43 100644
--- a/flexiapi/app/Http/Controllers/Api/MessageController.php
+++ b/flexiapi/app/Http/Controllers/Api/Admin/MessageController.php
@@ -1,6 +1,6 @@
.
+*/
+
+namespace App\Rules;
+
+use App\AccountCreationRequestToken as AppAccountCreationRequestToken;
+use App\Http\Controllers\Account\AuthenticateController;
+use Illuminate\Contracts\Validation\Rule;
+
+class AccountCreationRequestToken implements Rule
+{
+ public function passes($attribute, $value)
+ {
+ return AppAccountCreationRequestToken::where('token', $value)->where('used', false)->exists()
+ && strlen($value) == AuthenticateController::$emailCodeSize;
+ }
+
+ public function message()
+ {
+ return 'Please provide a valid account_creation_request_token';
+ }
+}
diff --git a/flexiapi/app/Rules/AccountCreationToken.php b/flexiapi/app/Rules/AccountCreationToken.php
index 39679fb..c1b815a 100644
--- a/flexiapi/app/Rules/AccountCreationToken.php
+++ b/flexiapi/app/Rules/AccountCreationToken.php
@@ -1,4 +1,21 @@
.
+*/
namespace App\Rules;
diff --git a/flexiapi/app/Rules/BlacklistedUsername.php b/flexiapi/app/Rules/BlacklistedUsername.php
index b731a4b..6092c57 100644
--- a/flexiapi/app/Rules/BlacklistedUsername.php
+++ b/flexiapi/app/Rules/BlacklistedUsername.php
@@ -1,4 +1,21 @@
.
+*/
namespace App\Rules;
diff --git a/flexiapi/database/migrations/2023_05_22_120505_make_pn_attributes_nullable_account_creation_tokens_table.php b/flexiapi/database/migrations/2023_05_22_120505_make_pn_attributes_nullable_account_creation_tokens_table.php
new file mode 100644
index 0000000..1ae21e5
--- /dev/null
+++ b/flexiapi/database/migrations/2023_05_22_120505_make_pn_attributes_nullable_account_creation_tokens_table.php
@@ -0,0 +1,29 @@
+string('pn_provider')->nullable(true)->change();
+ $table->string('pn_param')->nullable(true)->change();
+ $table->string('pn_prid')->nullable(true)->change();
+ });
+ }
+
+ public function down()
+ {
+ AccountCreationToken::whereNull('pn_provider')->delete();
+
+ Schema::table('account_creation_tokens', function (Blueprint $table) {
+ $table->string('pn_provider')->nullable(false)->change();
+ $table->string('pn_param')->nullable(false)->change();
+ $table->string('pn_prid')->nullable(false)->change();
+ });
+ }
+}
diff --git a/flexiapi/database/migrations/2023_05_22_123231_create_account_creation_request_tokens_table.php b/flexiapi/database/migrations/2023_05_22_123231_create_account_creation_request_tokens_table.php
new file mode 100644
index 0000000..51b84a0
--- /dev/null
+++ b/flexiapi/database/migrations/2023_05_22_123231_create_account_creation_request_tokens_table.php
@@ -0,0 +1,29 @@
+id();
+ $table->string('token', 16)->index();
+ $table->boolean('used')->default(false);
+ $table->dateTime('validated_at')->nullable();
+
+ $table->bigInteger('acc_creation_token_id')->unsigned()->nullable();
+ $table->foreign('acc_creation_token_id')->references('id')
+ ->on('account_creation_tokens')->onDelete('cascade');
+
+ $table->timestamps();
+ });
+ }
+
+ public function down()
+ {
+ Schema::dropIfExists('account_creation_request_tokens');
+ }
+}
diff --git a/flexiapi/public/css/style.css b/flexiapi/public/css/style.css
index 6632bbc..e82238a 100644
--- a/flexiapi/public/css/style.css
+++ b/flexiapi/public/css/style.css
@@ -29,6 +29,10 @@ body > div {
max-width: 800px;
}
+.container.large {
+ max-width: 1024px;
+}
+
body > footer::before {
background-color: white;
background-position: bottom center;
diff --git a/flexiapi/resources/views/account/creation_request_token/check.blade.php b/flexiapi/resources/views/account/creation_request_token/check.blade.php
new file mode 100644
index 0000000..bc2c421
--- /dev/null
+++ b/flexiapi/resources/views/account/creation_request_token/check.blade.php
@@ -0,0 +1,13 @@
+@extends('layouts.main')
+
+@section('content')
+
+
+ {!! Form::open(['route' => 'account.creation_request_token.validate']) !!}
+ {!! Form::hidden('account_creation_request_token', $account_creation_request_token->token) !!}
+ @include('parts.captcha')
+ {!! Form::submit('I\'m not a robot', ['class' => 'btn btn-primary btn-centered']) !!}
+ {!! Form::close() !!}
+
+
+@endsection
\ No newline at end of file
diff --git a/flexiapi/resources/views/account/creation_request_token/valid.blade.php b/flexiapi/resources/views/account/creation_request_token/valid.blade.php
new file mode 100644
index 0000000..997814b
--- /dev/null
+++ b/flexiapi/resources/views/account/creation_request_token/valid.blade.php
@@ -0,0 +1,6 @@
+@extends('layouts.main')
+
+@section('content')
+ Thanks for the validation
+ You can now continue your registration process in the application
+@endsection
\ No newline at end of file
diff --git a/flexiapi/resources/views/api/documentation.blade.php b/flexiapi/resources/views/api/documentation.blade.php
index 2ef60d1..b5f4edf 100644
--- a/flexiapi/resources/views/api/documentation.blade.php
+++ b/flexiapi/resources/views/api/documentation.blade.php
@@ -1,4 +1,4 @@
-@extends('layouts.main')
+@extends('layouts.main', ['large' => true])
@section('content')
{{-- This view is only a wrapper for the markdown page --}}
diff --git a/flexiapi/resources/views/api/documentation_markdown.blade.php b/flexiapi/resources/views/api/documentation_markdown.blade.php
index dd81bad..a75df97 100644
--- a/flexiapi/resources/views/api/documentation_markdown.blade.php
+++ b/flexiapi/resources/views/api/documentation_markdown.blade.php
@@ -78,9 +78,19 @@ You can find more documentation on the related [IETF RFC-7616](https://tools.iet
Public
Returns `pong`
+## Account Creation Request Tokens
+
+An `account_creation_request_token` is a unique token that can be validated and then used to generate a valid `account_creation_token`.
+
+### `POST /account_creation_request_tokens`
+Public
+
+Create and return an `account_creation_request_token` that should then be validated to be used.
+
+
## Account Creation Tokens
-An account creation token is a unique token that allow the creation of a **unique** account.
+An `account_creation_token` is a unique token that allow the creation of a **unique** account.
### `POST /account_creation_tokens/send-by-push`
Public
@@ -94,6 +104,16 @@ JSON parameters:
* `pn_param` the push notification parameter
* `pn_prid` the push notification unique id
+### `POST /account_creation_tokens/using-account-creation-request-token`
+Public
+Create an `account_creation_token` using an `account_creation_request_token`.
+Return an `account_creation_token`.
+Return `403` if the `account_creation_request_token` provided is not valid or expired otherwise.
+
+JSON parameters:
+
+* `account_creation_request_token` required
+
### `POST /account_creation_tokens`
Admin
diff --git a/flexiapi/resources/views/layouts/main.blade.php b/flexiapi/resources/views/layouts/main.blade.php
index a8e8676..68d12e3 100644
--- a/flexiapi/resources/views/layouts/main.blade.php
+++ b/flexiapi/resources/views/layouts/main.blade.php
@@ -33,7 +33,7 @@
@endsection
@section('body')
-
+
@include('parts.errors')
@yield('content')
diff --git a/flexiapi/routes/api.php b/flexiapi/routes/api.php
index 92e6190..e8508f8 100644
--- a/flexiapi/routes/api.php
+++ b/flexiapi/routes/api.php
@@ -26,59 +26,60 @@ Route::middleware('auth:api')->get('/user', function (Request $request) {
});
Route::get('ping', 'Api\PingController@ping');
-Route::post('account_creation_tokens/send-by-push', 'Api\AccountCreationTokenController@sendByPush');
-// Old URL, for retro-compatibility
-Route::post('tokens', 'Api\AccountCreationTokenController@sendByPush');
-Route::get('accounts/{sip}/info', 'Api\AccountController@info');
+Route::post('account_creation_request_tokens', 'Api\Account\CreationRequestToken@create');
+Route::post('account_creation_tokens/send-by-push', 'Api\Account\CreationTokenController@sendByPush');
+Route::post('account_creation_tokens/using-account-creation-request-token', 'Api\Account\CreationTokenController@usingAccountRequestToken');
+Route::post('accounts/with-account-creation-token', 'Api\Account\AccountController@store');
-Route::post('accounts/with-account-creation-token', 'Api\AccountController@store');
-// Old URL, for retro-compatibility
-Route::post('accounts/with-token', 'Api\AccountController@store');
+Route::get('accounts/{sip}/info', 'Api\Account\AccountController@info');
-Route::post('accounts/{sip}/activate/email', 'Api\AccountController@activateEmail');
-Route::post('accounts/{sip}/activate/phone', 'Api\AccountController@activatePhone');
+Route::post('accounts/{sip}/activate/email', 'Api\Account\AccountController@activateEmail');
+Route::post('accounts/{sip}/activate/phone', 'Api\Account\AccountController@activatePhone');
// /!\ Dangerous endpoints
-Route::post('accounts/public', 'Api\AccountController@storePublic');
-Route::get('accounts/{sip}/recover/{recovery_key}', 'Api\AccountController@recoverUsingKey');
-Route::post('accounts/recover-by-phone', 'Api\AccountController@recoverByPhone');
-Route::get('accounts/{phone}/info-by-phone', 'Api\AccountController@phoneInfo');
+Route::post('accounts/public', 'Api\Account\AccountController@storePublic');
+Route::get('accounts/{sip}/recover/{recovery_key}', 'Api\Account\AccountController@recoverUsingKey');
+Route::post('accounts/recover-by-phone', 'Api\Account\AccountController@recoverByPhone');
+Route::get('accounts/{phone}/info-by-phone', 'Api\Account\AccountController@phoneInfo');
-Route::post('accounts/auth_token', 'Api\AuthTokenController@store');
+Route::post('accounts/auth_token', 'Api\Account\AuthTokenController@store');
-Route::get('accounts/me/api_key/{auth_token}', 'Api\ApiKeyController@generateFromToken')->middleware('cookie', 'cookie.encrypt');
+Route::get('accounts/me/api_key/{auth_token}', 'Api\Account\ApiKeyController@generateFromToken')->middleware('cookie', 'cookie.encrypt');
Route::group(['middleware' => ['auth.digest_or_key']], function () {
Route::get('statistic/month', 'Api\StatisticController@month');
Route::get('statistic/week', 'Api\StatisticController@week');
Route::get('statistic/day', 'Api\StatisticController@day');
- Route::get('accounts/auth_token/{auth_token}/attach', 'Api\AuthTokenController@attach');
+ Route::get('accounts/auth_token/{auth_token}/attach', 'Api\Account\AuthTokenController@attach');
- Route::get('accounts/me/api_key', 'Api\ApiKeyController@generate')->middleware('cookie', 'cookie.encrypt');
+ Route::get('accounts/me/api_key', 'Api\Account\ApiKeyController@generate')->middleware('cookie', 'cookie.encrypt');
- Route::get('accounts/me', 'Api\AccountController@show');
- Route::delete('accounts/me', 'Api\AccountController@delete');
- Route::get('accounts/me/provision', 'Api\AccountController@provision');
+ Route::get('accounts/me', 'Api\Account\AccountController@show');
+ Route::delete('accounts/me', 'Api\Account\AccountController@delete');
+ Route::get('accounts/me/provision', 'Api\Account\AccountController@provision');
- Route::post('accounts/me/phone/request', 'Api\AccountPhoneController@requestUpdate');
- Route::post('accounts/me/phone', 'Api\AccountPhoneController@update');
+ Route::post('accounts/me/phone/request', 'Api\Account\PhoneController@requestUpdate');
+ Route::post('accounts/me/phone', 'Api\Account\PhoneController@update');
- Route::get('accounts/me/devices', 'Api\DeviceController@index');
- Route::delete('accounts/me/devices/{uuid}', 'Api\DeviceController@destroy');
+ Route::get('accounts/me/devices', 'Api\Account\DeviceController@index');
+ Route::delete('accounts/me/devices/{uuid}', 'Api\Account\DeviceController@destroy');
- Route::post('accounts/me/email/request', 'Api\EmailController@requestUpdate');
- Route::post('accounts/me/password', 'Api\PasswordController@update');
+ Route::post('accounts/me/email/request', 'Api\Account\EmailController@requestUpdate');
+ Route::post('accounts/me/password', 'Api\Account\PasswordController@update');
- Route::get('accounts/me/contacts/{sip}', 'Api\AccountContactController@show');
- Route::get('accounts/me/contacts', 'Api\AccountContactController@index');
+ Route::get('accounts/me/contacts/{sip}', 'Api\Account\ContactController@show');
+ Route::get('accounts/me/contacts', 'Api\Account\ContactController@index');
Route::group(['middleware' => ['auth.admin']], function () {
if (!empty(config('app.linphone_daemon_unix_pipe'))) {
- Route::post('messages', 'Api\MessageController@send');
+ Route::post('messages', 'Api\Admin\MessageController@send');
}
+ // Account creation token
+ Route::post('account_creation_tokens', 'Api\Admin\AccountCreationTokenController@create');
+
// Accounts
Route::get('accounts/{id}/activate', 'Api\Admin\AccountController@activate');
Route::get('accounts/{id}/deactivate', 'Api\Admin\AccountController@deactivate');
diff --git a/flexiapi/routes/web.php b/flexiapi/routes/web.php
index c2a896d..ed94521 100644
--- a/flexiapi/routes/web.php
+++ b/flexiapi/routes/web.php
@@ -36,6 +36,9 @@ if (config('app.web_panel')) {
Route::get('authenticate/qrcode/{token?}', 'Account\AuthenticateController@loginAuthToken')->name('account.authenticate.auth_token');
}
+Route::get('creation_token/check/{token}', 'Account\CreationRequestTokenController@check')->name('account.creation_request_token.check');
+Route::post('creation_token/validate', 'Account\CreationRequestTokenController@validateToken')->name('account.creation_request_token.validate');
+
Route::group(['middleware' => 'auth.digest_or_key'], function () {
Route::get('provisioning/me', 'Account\ProvisioningController@me')->name('provisioning.me');
diff --git a/flexiapi/tests/Feature/ApiAccountCreationTokenTest.php b/flexiapi/tests/Feature/ApiAccountCreationTokenTest.php
index f1db9a7..9a3a0ae 100644
--- a/flexiapi/tests/Feature/ApiAccountCreationTokenTest.php
+++ b/flexiapi/tests/Feature/ApiAccountCreationTokenTest.php
@@ -19,17 +19,23 @@
namespace Tests\Feature;
+use App\AccountCreationRequestToken;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
use App\AccountCreationToken;
+use App\Admin;
+use Carbon\Carbon;
class ApiAccountCreationTokenTest extends TestCase
{
use RefreshDatabase;
protected $tokenRoute = '/api/account_creation_tokens/send-by-push';
+ protected $tokenRequestRoute = '/api/account_creation_request_tokens';
+ protected $tokenUsingCreationTokenRoute = '/api/account_creation_tokens/using-account-creation-request-token';
protected $accountRoute = '/api/accounts/with-account-creation-token';
+ protected $adminRoute = '/api/account_creation_tokens';
protected $method = 'POST';
protected $pnProvider = 'provider';
@@ -52,51 +58,24 @@ class ApiAccountCreationTokenTest extends TestCase
$response->assertStatus(503);
}
- /**
- * For retro-compatibility only
- */
- public function testRetrocopatibilityToken()
+ public function testAdminEndpoint()
{
- $token = AccountCreationToken::factory()->create();
+ $admin = Admin::factory()->create();
+ $admin->account->generateApiKey();
- $response = $this->json($this->method, '/api/tokens', [
- 'pn_provider' => $token->pn_provider,
- 'pn_param' => $token->pn_param,
- 'pn_prid' => $token->pn_prid
+ $response = $this->keyAuthenticated($admin->account)
+ ->json($this->method, $this->adminRoute)
+ ->assertStatus(201);
+
+ $this->assertDatabaseHas('account_creation_tokens', [
+ 'token' => $response->json()['token']
]);
- $response->assertStatus(503);
}
public function testInvalidToken()
{
$token = AccountCreationToken::factory()->create();
- // Valid token
- $response = $this->json($this->method, '/api/accounts/with-token', [
- 'username' => 'username',
- 'algorithm' => 'SHA-256',
- 'password' => '2',
- 'token' => $token->token
- ]);
- $response->assertStatus(200);
-
- // Expired token
- $response = $this->json($this->method, '/api/accounts/with-token', [
- 'username' => 'username2',
- 'algorithm' => 'SHA-256',
- 'password' => '2',
- 'token' => $token->token
- ]);
- $response->assertStatus(422);
- }
-
- /**
- * For retrocompatibility only
- */
- public function testRetrocompatibilityInvalidToken()
- {
- $token = AccountCreationToken::factory()->create();
-
// Invalid token
$response = $this->json($this->method, $this->accountRoute, [
'username' => 'username',
@@ -125,9 +104,6 @@ class ApiAccountCreationTokenTest extends TestCase
$response->assertStatus(422);
}
- /**
- * Test username blacklist
- */
public function testBlacklistedUsername()
{
$token = AccountCreationToken::factory()->create();
@@ -165,4 +141,34 @@ class ApiAccountCreationTokenTest extends TestCase
$response->assertStatus(200);
}
+
+ public function testAccountCreationRequestToken()
+ {
+ $response = $this->json($this->method, $this->tokenRequestRoute);
+ $response->assertStatus(201);
+ $creationRequestToken = $response->json()['token'];
+
+ // Validate the creation request token
+ AccountCreationRequestToken::where('token', $creationRequestToken)->update(['validated_at' => Carbon::now()]);
+
+ $response = $this->json($this->method, $this->tokenUsingCreationTokenRoute, [
+ 'account_creation_request_token' => $creationRequestToken
+ ])->assertStatus(201);
+
+ $creationToken = $response->json()['token'];
+
+ $this->assertDatabaseHas('account_creation_request_tokens', [
+ 'token' => $creationRequestToken,
+ 'used' => true
+ ]);
+
+ $this->assertDatabaseHas('account_creation_tokens', [
+ 'token' => $creationToken
+ ]);
+
+ $this->assertSame(
+ AccountCreationRequestToken::where('token', $creationRequestToken)->first()->accountCreationToken->id,
+ AccountCreationToken::where('token', $creationToken)->first()->id
+ );
+ }
}