diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1857179..cc037b2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -45,6 +45,7 @@ v2.0
- Fix FLEXIAPI-321 Disable the account creation button when the Space is full for admins
- Fix FLEXIAPI-322 Api Keys documentation
- Fix FLEXIAPI-328 Set realm on Space creation, limit the update if some accounts are present
+- Fix FLEXIAPI-325 Add endpoints to send the password reset and provisioning emails
v1.6
----
diff --git a/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php b/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php
index 65afd37..f2b6482 100644
--- a/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php
+++ b/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php
@@ -21,14 +21,19 @@ namespace App\Http\Controllers\Api\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
+use Illuminate\Support\Str;
use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Mail;
use App\Account;
use App\AccountTombstone;
use App\AccountType;
use App\ContactsList;
+use App\ResetPasswordEmailToken;
use App\Http\Requests\Account\Create\Api\AsAdminRequest;
use App\Http\Requests\Account\Update\Api\AsAdminRequest as ApiAsAdminRequest;
+use App\Mail\Provisioning;
+use App\Mail\ResetPassword;
use App\Services\AccountService;
use App\Space;
@@ -198,4 +203,36 @@ class AccountController extends Controller
return Account::findOrFail($accountId)->contactsLists()->detach($contactsListId);
}
+
+ /**
+ * Emails
+ */
+
+ public function sendProvisioningEmail(int $accountId)
+ {
+ $account = Account::findOrFail($accountId);
+
+ if (!$account->email) abort(403, 'No email configured');
+
+ $account->provision();
+
+ Mail::to($account)->send(new Provisioning($account));
+
+ Log::channel('events')->info('API: Sending provisioning email', ['id' => $account->identifier]);
+ }
+
+ public function sendResetPasswordEmail(int $accountId)
+ {
+ $account = Account::findOrFail($accountId);
+
+ if (!$account->email) abort(403, 'No email configured');
+
+ $resetPasswordEmail = new ResetPasswordEmailToken;
+ $resetPasswordEmail->account_id = $account->id;
+ $resetPasswordEmail->token = Str::random(16);
+ $resetPasswordEmail->email = $account->email;
+ $resetPasswordEmail->save();
+
+ Mail::to($account)->send(new ResetPassword($account));
+ }
}
diff --git a/flexiapi/resources/views/api/documentation_markdown.blade.php b/flexiapi/resources/views/api/documentation_markdown.blade.php
index 0e777bf..f7d5403 100644
--- a/flexiapi/resources/views/api/documentation_markdown.blade.php
+++ b/flexiapi/resources/views/api/documentation_markdown.blade.php
@@ -501,6 +501,16 @@ Unblock an account.
Provision an account by generating a fresh `provisioning_token`.
+### `POST /accounts/{id}/send_provisioning_email`
+Admin
+
+Send a provisioning email to the account.
+
+### `POST /accounts/{id}/send_reset_password_email`
+Admin
+
+Send a password reset email to the account.
+
## Accounts email
### `POST /accounts/me/email/request`
diff --git a/flexiapi/routes/api.php b/flexiapi/routes/api.php
index 3981c4f..ec4b468 100644
--- a/flexiapi/routes/api.php
+++ b/flexiapi/routes/api.php
@@ -118,6 +118,8 @@ Route::group(['middleware' => ['auth.jwt', 'auth.digest_or_key', 'auth.check_blo
Route::post('{account_id}/block', 'block');
Route::post('{account_id}/unblock', 'unblock');
Route::get('{account_id}/provision', 'provision');
+ Route::post('{account_id}/send_provisioning_email', 'sendProvisioningEmail');
+ Route::post('{account_id}/send_reset_password_email', 'sendResetPasswordEmail');
Route::post('/', 'store');
Route::put('{account_id}', 'update');
diff --git a/flexiapi/tests/Feature/ApiAccountTest.php b/flexiapi/tests/Feature/ApiAccountTest.php
index cbb5e94..bd8a3d5 100644
--- a/flexiapi/tests/Feature/ApiAccountTest.php
+++ b/flexiapi/tests/Feature/ApiAccountTest.php
@@ -669,6 +669,49 @@ class ApiAccountTest extends TestCase
->json('GET', '/api/accounts/me');
}
+ public function testSendProvisioningEmail()
+ {
+ $password = Password::factory()->create();
+ $account = $password->account;
+
+ $admin = Account::factory()->admin()->create();
+ $admin->generateUserApiKey();
+ $admin->save();
+
+ $this->keyAuthenticated($admin)
+ ->json('POST', $this->route . '/' . $account->id . '/send_provisioning_email')
+ ->assertStatus(403);
+
+ $account->email = 'test@email.com';
+ $account->save();
+
+ $this->keyAuthenticated($admin)
+ ->json('POST', $this->route . '/' . $account->id . '/send_provisioning_email')
+ ->assertStatus(200);
+ }
+
+ public function testSendResetPasswordEmail()
+ {
+ $password = Password::factory()->create();
+ $account = $password->account;
+
+ $admin = Account::factory()->admin()->create();
+ $admin->generateUserApiKey();
+ $admin->save();
+
+ $this->keyAuthenticated($admin)
+ ->json('POST', $this->route . '/' . $account->id . '/send_reset_password_email')
+ ->assertStatus(403);
+
+ $account->email = 'test@email.com';
+ $account->save();
+
+ $this->keyAuthenticated($admin)
+ ->json('POST', $this->route . '/' . $account->id . '/send_reset_password_email')
+ ->assertStatus(200);
+ }
+
+
public function testEditAdmin()
{
$password = Password::factory()->create();