Page MenuHomePhorge

D5577.1775231910.diff
No OneTemporary

Authored By
Unknown
Size
114 KB
Referenced Files
None
Subscribers
None

D5577.1775231910.diff

diff --git a/src/app/Auth/OAuth.php b/src/app/Auth/OAuth.php
--- a/src/app/Auth/OAuth.php
+++ b/src/app/Auth/OAuth.php
@@ -113,6 +113,7 @@
return response()->json([
'status' => 'success',
+ // Client (e.g. webmail) location to redirect to
'redirectUrl' => $response->getHeader('Location')[0],
]);
}
diff --git a/src/app/CompanionApp.php b/src/app/CompanionApp.php
--- a/src/app/CompanionApp.php
+++ b/src/app/CompanionApp.php
@@ -12,6 +12,14 @@
* The eloquent definition of a CompanionApp.
*
* A CompanionApp is an kolab companion app that the user registered
+ *
+ * @property string $device_id
+ * @property string $id App identifier
+ * @property string $name App name
+ * @property ?string $notification_token Firebase notification token
+ * @property bool $mfa_enabled
+ * @property string $oauth_client_id Oauth client identifier
+ * @property int $user_id User (owner) identifier
*/
class CompanionApp extends Model
{
diff --git a/src/app/Enums/ProcessState.php b/src/app/Enums/ProcessState.php
new file mode 100644
--- /dev/null
+++ b/src/app/Enums/ProcessState.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace App\Enums;
+
+/**
+ * Enumeration of ProcessState
+ */
+enum ProcessState: string
+{
+ case Waiting = 'waiting';
+ case Running = 'running';
+ case Failed = 'failed';
+ case Done = 'done';
+}
diff --git a/src/app/Http/Controllers/API/AuthController.php b/src/app/Http/Controllers/API/AuthController.php
--- a/src/app/Http/Controllers/API/AuthController.php
+++ b/src/app/Http/Controllers/API/AuthController.php
@@ -25,10 +25,8 @@
* Get user information.
*
* Note that the same information is by default included in the `auth/login` response.
- *
- * @return JsonResponse
*/
- public function info()
+ public function info(): JsonResponse
{
$response = new UserInfoResource($this->guard()->user());
@@ -43,7 +41,7 @@
* @param string $password Plain text password
* @param string|null $secondFactor Second factor code if available
*/
- public static function logonResponse(User $user, string $password, ?string $secondFactor = null)
+ public static function logonResponse(User $user, string $password, ?string $secondFactor = null): JsonResponse
{
$mode = request()->mode; // have to be before we make a request below
@@ -69,13 +67,9 @@
*
* Returns an authentication token(s) and user information.
*
- * @param Request $request The API request
- *
- * @return JsonResponse
- *
* @unauthenticated
*/
- public function login(Request $request)
+ public function login(Request $request): JsonResponse
{
$v = Validator::make(
$request->all(),
@@ -116,10 +110,8 @@
* @param ServerRequestInterface $psrRequest PSR request
* @param Request $request The API request
* @param AuthorizationServer $server Authorization server
- *
- * @return JsonResponse
*/
- public function oauthApprove(ServerRequestInterface $psrRequest, Request $request, AuthorizationServer $server)
+ public function oauthApprove(ServerRequestInterface $psrRequest, Request $request, AuthorizationServer $server): JsonResponse
{
$user = $this->guard()->user();
@@ -128,10 +120,8 @@
/**
* Get the authenticated User information (using access token claims)
- *
- * @return JsonResponse
*/
- public function oauthUserInfo()
+ public function oauthUserInfo(): JsonResponse
{
$user = $this->guard()->user();
@@ -143,11 +133,9 @@
/**
* Get geo-location
*
- * @return JsonResponse
- *
* @unauthenticated
*/
- public function location()
+ public function location(): JsonResponse
{
$ip = request()->ip();
@@ -165,10 +153,8 @@
* Logout a user.
*
* Revokes the authentication token.
- *
- * @return JsonResponse
*/
- public function logout()
+ public function logout(): JsonResponse
{
$tokenId = $this->guard()->user()->token()->id;
$tokenRepository = app(TokenRepository::class);
@@ -188,10 +174,8 @@
/**
* Refresh a session token.
- *
- * @return JsonResponse
*/
- public function refresh(Request $request)
+ public function refresh(Request $request): JsonResponse
{
$v = Validator::make($request->all(), [
// Request user information in the response
diff --git a/src/app/Http/Controllers/API/PasswordResetController.php b/src/app/Http/Controllers/API/PasswordResetController.php
--- a/src/app/Http/Controllers/API/PasswordResetController.php
+++ b/src/app/Http/Controllers/API/PasswordResetController.php
@@ -7,6 +7,7 @@
use App\Rules\Password;
use App\User;
use App\VerificationCode;
+use Dedoc\Scramble\Attributes\BodyParameter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -19,17 +20,13 @@
class PasswordResetController extends Controller
{
/**
- * Sends password reset code to the user's external email
+ * Initialize password reset via user's external email
*
- * Verifies user email, sends verification email message.
- *
- * @param Request $request HTTP request
- *
- * @return JsonResponse JSON response
+ * Verifies user email, creates a verification code and initiates a job to send an email message.
*
* @unauthenticated
*/
- public function init(Request $request)
+ public function init(Request $request): JsonResponse
{
// Check required fields
$v = Validator::make($request->all(), ['email' => 'required|email']);
@@ -65,25 +62,27 @@
// Send email/sms message
PasswordResetJob::dispatch($code);
- return response()->json(['status' => 'success', 'code' => $code->code]);
+ return response()->json([
+ 'status' => 'success',
+ // Verification code identifier
+ 'code' => $code->code,
+ ]);
}
/**
* Validation of the verification code.
*
- * @param Request $request HTTP request
- *
- * @return JsonResponse JSON response
- *
* @unauthenticated
*/
- public function verify(Request $request)
+ public function verify(Request $request): JsonResponse
{
// Validate the request args
$v = Validator::make(
$request->all(),
[
+ // Verification code identifier
'code' => 'required',
+ // Validation code secret
'short_code' => 'required',
]
);
@@ -111,7 +110,8 @@
return response()->json([
'status' => 'success',
- // we need user's ID for e.g. password policy checks
+ // @var int User identifier
+ // We need user ID for e.g. password policy checks
'userId' => $code->user_id,
]);
}
@@ -119,13 +119,12 @@
/**
* Password reset (using an email verification code)
*
- * @param Request $request HTTP request
- *
- * @return JsonResponse JSON response
+ * On success user will be auto-logged-in with a response same as for `auth/login` call.
*
* @unauthenticated
*/
- public function reset(Request $request)
+ #[BodyParameter('secondfactor', description: '2FA token (required if user enabled 2FA)', type: 'string')]
+ public function reset(Request $request): JsonResponse
{
$v = $this->verify($request);
if ($v->status() !== 200) {
@@ -137,7 +136,10 @@
// Validate the password
$v = Validator::make(
$request->all(),
- ['password' => ['required', 'confirmed', new Password($user->walletOwner())]]
+ [
+ // New password
+ 'password' => ['required', 'confirmed', new Password($user->walletOwner())],
+ ]
);
if ($v->fails()) {
@@ -150,13 +152,13 @@
/**
* Expired password change (using user credentials)
*
- * @param Request $request HTTP request
- *
- * @return JsonResponse JSON response
+ * On success user will be auto-logged-in with a response same as for `auth/login` call.
*
* @unauthenticated
*/
- public function resetExpired(Request $request)
+ #[BodyParameter('email', description: 'User email address', type: 'string', required: true)]
+ #[BodyParameter('secondfactor', description: '2FA token (required if user enabled 2FA)', type: 'string')]
+ public function resetExpired(Request $request): JsonResponse
{
$user = User::where('email', $request->email)->first();
@@ -178,6 +180,7 @@
$v = Validator::make(
$request->all(),
[
+ // New password
'new_password' => ['required', 'confirmed', new Password($user->walletOwner())],
]
);
@@ -193,12 +196,8 @@
/**
* Create a verification code for the current user.
- *
- * @param Request $request HTTP request
- *
- * @return JsonResponse JSON response
*/
- public function codeCreate(Request $request)
+ public function codeCreate(Request $request): JsonResponse
{
// Generate the verification code
$code = new VerificationCode();
@@ -214,8 +213,11 @@
return response()->json([
'status' => 'success',
+ // Verification code identifier
'code' => $code->code,
+ // Verification code secret
'short_code' => $code->short_code,
+ // Code expiration date-time
'expires_at' => $code->expires_at->toDateTimeString(),
]);
}
@@ -223,11 +225,9 @@
/**
* Delete a verification code.
*
- * @param string $id Code identifier
- *
- * @return JsonResponse The response
+ * @param string $id Verification code identifier
*/
- public function codeDelete($id)
+ public function codeDelete($id): JsonResponse
{
// Accept <short-code>-<code> input
if (strpos($id, '-')) {
diff --git a/src/app/Http/Controllers/API/SignupController.php b/src/app/Http/Controllers/API/SignupController.php
--- a/src/app/Http/Controllers/API/SignupController.php
+++ b/src/app/Http/Controllers/API/SignupController.php
@@ -40,13 +40,9 @@
/**
* List of plans for signup.
*
- * @param Request $request HTTP request
- *
- * @return JsonResponse JSON response
- *
* @unauthenticated
*/
- public function plans(Request $request)
+ public function plans(Request $request): JsonResponse
{
// Use reverse order just to have individual on left, group on right ;)
// But prefer monthly on left, yearly on right
@@ -64,13 +60,9 @@
/**
* List of public domains for signup.
*
- * @param Request $request HTTP request
- *
- * @return JsonResponse JSON response
- *
* @unauthenticated
*/
- public function domains(Request $request)
+ public function domains(Request $request): JsonResponse
{
return response()->json([
'status' => 'success',
@@ -84,10 +76,6 @@
*
* Verifies user name and email, sends verification message. Returns the verification code.
*
- * @param Request $request HTTP request
- *
- * @return JsonResponse JSON response
- *
* @unauthenticated
*/
#[BodyParameter('plan', description: 'Plan identifier', type: 'string', required: true)]
@@ -97,7 +85,7 @@
#[BodyParameter('referral', description: 'Referral program code', type: 'string')]
#[BodyParameter('voucher', description: 'Voucher code', type: 'string')]
#[BodyParameter('token', description: 'Signup token (required for token-mode signup)', type: 'string')]
- public function init(Request $request)
+ public function init(Request $request): JsonResponse
{
// Don't allow URLs in user names preventing abuse of signup email
// FIXME: I suppose we could also not use "Dear <user name>" in email
@@ -171,11 +159,9 @@
*
* @param string $id Signup invitation identifier
*
- * @return JsonResponse|void
- *
* @unauthenticated
*/
- public function invitation($id)
+ public function invitation($id): JsonResponse
{
$invitation = SignupInvitation::withEnvTenantContext()->find($id);
@@ -195,13 +181,11 @@
* @param Request $request HTTP request
* @param bool $update Update the signup code record
*
- * @return JsonResponse JSON response
- *
* @unauthenticated
*/
#[BodyParameter('code', description: 'Verification code', type: 'string', required: true)]
#[BodyParameter('short_code', description: 'Short code', type: 'string', required: true)]
- public function verify(Request $request, $update = true)
+ public function verify(Request $request, $update = true): JsonResponse
{
// Validate the request args
$v = Validator::make(
@@ -262,10 +246,6 @@
/**
* Validates the input to the final signup request.
*
- * @param Request $request HTTP request
- *
- * @return JsonResponse JSON response
- *
* @unauthenticated
*/
#[BodyParameter('login', description: 'User login', type: 'string', required: true)]
@@ -277,7 +257,7 @@
#[BodyParameter('token', description: 'Signup token (required for mode=token plans)', type: 'string')]
#[BodyParameter('first_name', description: 'First name', type: 'string')]
#[BodyParameter('last_name', description: 'Last name', type: 'string')]
- public function signupValidate(Request $request)
+ public function signupValidate(Request $request): JsonResponse
{
$rules = [
'login' => 'required|min:2',
@@ -391,10 +371,6 @@
*
* On success creates a new account and returns authentication token(s) and user information.
*
- * @param Request $request HTTP request
- *
- * @return JsonResponse JSON response
- *
* @unauthenticated
*/
#[BodyParameter('login', description: 'User login', type: 'string', required: true)]
@@ -406,7 +382,7 @@
#[BodyParameter('token', description: 'Signup token (required for mode=token plans)', type: 'string')]
#[BodyParameter('first_name', description: 'First name', type: 'string')]
#[BodyParameter('last_name', description: 'Last name', type: 'string')]
- public function signup(Request $request)
+ public function signup(Request $request): JsonResponse
{
$v = $this->signupValidate($request);
if ($v->status() !== 200) {
@@ -620,9 +596,9 @@
*
* @param Request $request HTTP request
*
- * @returns \App\Plan Plan object selected for current signup process
+ * @returns ?Plan Plan object selected for current signup process
*/
- protected function getPlan(Request $request)
+ protected function getPlan(Request $request): ?Plan
{
if (!$request->plan instanceof Plan) {
$plan = null;
diff --git a/src/app/Http/Controllers/API/V4/Admin/DiscountsController.php b/src/app/Http/Controllers/API/V4/Admin/DiscountsController.php
--- a/src/app/Http/Controllers/API/V4/Admin/DiscountsController.php
+++ b/src/app/Http/Controllers/API/V4/Admin/DiscountsController.php
@@ -13,10 +13,8 @@
* Returns (active) discounts defined in the system for the user context.
*
* @param int $id User identifier
- *
- * @return JsonResponse JSON response
*/
- public function userDiscounts($id)
+ public function userDiscounts($id): JsonResponse
{
$user = User::find($id);
diff --git a/src/app/Http/Controllers/API/V4/Admin/DomainsController.php b/src/app/Http/Controllers/API/V4/Admin/DomainsController.php
--- a/src/app/Http/Controllers/API/V4/Admin/DomainsController.php
+++ b/src/app/Http/Controllers/API/V4/Admin/DomainsController.php
@@ -15,20 +15,16 @@
* Remove the specified domain.
*
* @param string $id Domain identifier
- *
- * @return JsonResponse
*/
- public function destroy($id)
+ public function destroy($id): JsonResponse
{
return $this->errorResponse(404);
}
/**
* Search for domains
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$search = trim(request()->input('search'));
$owner = trim(request()->input('owner'));
@@ -71,10 +67,8 @@
/**
* Create a domain.
- *
- * @return JsonResponse
*/
- public function store(Request $request)
+ public function store(Request $request): JsonResponse
{
return $this->errorResponse(404);
}
@@ -84,10 +78,8 @@
*
* @param Request $request the API request
* @param string $id Domain identifier
- *
- * @return JsonResponse The response
*/
- public function suspend(Request $request, $id)
+ public function suspend(Request $request, $id): JsonResponse
{
$domain = Domain::find($id);
@@ -116,10 +108,8 @@
*
* @param Request $request the API request
* @param string $id Domain identifier
- *
- * @return JsonResponse The response
*/
- public function unsuspend(Request $request, $id)
+ public function unsuspend(Request $request, $id): JsonResponse
{
$domain = Domain::find($id);
diff --git a/src/app/Http/Controllers/API/V4/Admin/EventLogController.php b/src/app/Http/Controllers/API/V4/Admin/EventLogController.php
--- a/src/app/Http/Controllers/API/V4/Admin/EventLogController.php
+++ b/src/app/Http/Controllers/API/V4/Admin/EventLogController.php
@@ -15,10 +15,8 @@
* @param Request $request HTTP Request
* @param string $object_type Object type
* @param string $object_id Object id
- *
- * @return JsonResponse
*/
- public function index(Request $request, string $object_type, string $object_id)
+ public function index(Request $request, string $object_type, string $object_id): JsonResponse
{
$object_type = "App\\" . ucfirst($object_type);
diff --git a/src/app/Http/Controllers/API/V4/Admin/GroupsController.php b/src/app/Http/Controllers/API/V4/Admin/GroupsController.php
--- a/src/app/Http/Controllers/API/V4/Admin/GroupsController.php
+++ b/src/app/Http/Controllers/API/V4/Admin/GroupsController.php
@@ -13,10 +13,8 @@
{
/**
* Search for groups
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$search = trim(request()->input('search'));
$owner = trim(request()->input('owner'));
@@ -50,12 +48,8 @@
/**
* Create a new group.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function store(Request $request)
+ public function store(Request $request): JsonResponse
{
return $this->errorResponse(404);
}
@@ -65,10 +59,8 @@
*
* @param Request $request the API request
* @param string $id Group identifier
- *
- * @return JsonResponse The response
*/
- public function suspend(Request $request, $id)
+ public function suspend(Request $request, $id): JsonResponse
{
$group = Group::find($id);
@@ -97,10 +89,8 @@
*
* @param Request $request the API request
* @param string $id Group identifier
- *
- * @return JsonResponse The response
*/
- public function unsuspend(Request $request, $id)
+ public function unsuspend(Request $request, $id): JsonResponse
{
$group = Group::find($id);
diff --git a/src/app/Http/Controllers/API/V4/Admin/ResourcesController.php b/src/app/Http/Controllers/API/V4/Admin/ResourcesController.php
--- a/src/app/Http/Controllers/API/V4/Admin/ResourcesController.php
+++ b/src/app/Http/Controllers/API/V4/Admin/ResourcesController.php
@@ -11,10 +11,8 @@
{
/**
* Search for resources
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$search = trim(request()->input('search'));
$owner = trim(request()->input('owner'));
@@ -48,12 +46,8 @@
/**
* Create a new resource.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function store(Request $request)
+ public function store(Request $request): JsonResponse
{
return $this->errorResponse(404);
}
diff --git a/src/app/Http/Controllers/API/V4/Admin/SharedFoldersController.php b/src/app/Http/Controllers/API/V4/Admin/SharedFoldersController.php
--- a/src/app/Http/Controllers/API/V4/Admin/SharedFoldersController.php
+++ b/src/app/Http/Controllers/API/V4/Admin/SharedFoldersController.php
@@ -11,10 +11,8 @@
{
/**
* Search for shared folders
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$search = trim(request()->input('search'));
$owner = trim(request()->input('owner'));
@@ -48,12 +46,8 @@
/**
* Create a new shared folder.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function store(Request $request)
+ public function store(Request $request): JsonResponse
{
return $this->errorResponse(404);
}
diff --git a/src/app/Http/Controllers/API/V4/Admin/StatsController.php b/src/app/Http/Controllers/API/V4/Admin/StatsController.php
--- a/src/app/Http/Controllers/API/V4/Admin/StatsController.php
+++ b/src/app/Http/Controllers/API/V4/Admin/StatsController.php
@@ -39,10 +39,8 @@
* Fetch chart data
*
* @param string $chart Name of the chart
- *
- * @return JsonResponse
*/
- public function chart($chart)
+ public function chart($chart): JsonResponse
{
if (!preg_match('/^[a-z-]+$/', $chart)) {
return $this->errorResponse(404);
diff --git a/src/app/Http/Controllers/API/V4/Admin/UsersController.php b/src/app/Http/Controllers/API/V4/Admin/UsersController.php
--- a/src/app/Http/Controllers/API/V4/Admin/UsersController.php
+++ b/src/app/Http/Controllers/API/V4/Admin/UsersController.php
@@ -6,6 +6,7 @@
use App\Entitlement;
use App\EventLog;
use App\Group;
+use App\Http\Resources\UserResource;
use App\Payment;
use App\Resource;
use App\SharedFolder;
@@ -26,20 +27,16 @@
* Delete a user.
*
* @param string $id User identifier
- *
- * @return JsonResponse The response
*/
- public function destroy($id)
+ public function destroy($id): JsonResponse
{
return $this->errorResponse(404);
}
/**
* Searching of user accounts.
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$search = trim(request()->input('search'));
$owner = trim(request()->input('owner'));
@@ -147,16 +144,12 @@
}
}
- // Process the result
- $result = $result->map(
- function ($user) {
- return $this->objectToClient($user, true);
- }
- );
-
$result = [
- 'list' => $result,
+ // List of users
+ 'list' => UserResource::collection($result),
+ // @var int Number of entries in the list
'count' => count($result),
+ // @var string Response message
'message' => self::trans('app.search-foundxusers', ['x' => count($result)]),
];
@@ -168,10 +161,8 @@
*
* @param Request $request the API request
* @param string $id User identifier
- *
- * @return JsonResponse The response
*/
- public function reset2FA(Request $request, $id)
+ public function reset2FA(Request $request, $id): JsonResponse
{
$user = User::find($id);
@@ -202,10 +193,8 @@
*
* @param Request $request the API request
* @param string $id User identifier
- *
- * @return JsonResponse The response
*/
- public function resetGeoLock(Request $request, $id)
+ public function resetGeoLock(Request $request, $id): JsonResponse
{
$user = User::find($id);
@@ -230,10 +219,8 @@
*
* @param Request $request the API request
* @param string $id User identifier
- *
- * @return JsonResponse The response
*/
- public function resync(Request $request, $id)
+ public function resync(Request $request, $id): JsonResponse
{
$user = User::find($id);
@@ -261,10 +248,8 @@
* @param Request $request the API request
* @param string $id User identifier
* @param string $sku SKU title
- *
- * @return JsonResponse The response
*/
- public function setSku(Request $request, $id, $sku)
+ public function setSku(Request $request, $id, $sku): JsonResponse
{
// For now we allow adding the 'beta' SKU only
if ($sku != 'beta') {
@@ -309,12 +294,8 @@
/**
* Create a new user record.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function store(Request $request)
+ public function store(Request $request): JsonResponse
{
return $this->errorResponse(404);
}
@@ -324,10 +305,8 @@
*
* @param Request $request the API request
* @param string $id User identifier
- *
- * @return JsonResponse The response
*/
- public function suspend(Request $request, $id)
+ public function suspend(Request $request, $id): JsonResponse
{
$user = User::find($id);
@@ -360,10 +339,8 @@
*
* @param Request $request the API request
* @param string $id User identifier
- *
- * @return JsonResponse The response
*/
- public function unsuspend(Request $request, $id)
+ public function unsuspend(Request $request, $id): JsonResponse
{
$user = User::find($id);
@@ -396,10 +373,8 @@
*
* @param Request $request the API request
* @param string $id User identifier
- *
- * @return JsonResponse The response
*/
- public function update(Request $request, $id)
+ public function update(Request $request, $id): JsonResponse
{
$user = User::find($id);
@@ -447,15 +422,17 @@
* Inspect what kolab4 sees from the request.
*
* Useful for testing proxy settings and making sure the X-Forwarded-For Header is picked up.
- *
- * @return JsonResponse The response
*/
- public function inspectRequest(Request $request)
+ public function inspectRequest(Request $request): JsonResponse
{
return response()->json([
+ // Client IP address
'ip' => $request->ip(),
+ // Client IP addresses
'clientIps' => $request->getClientIps(),
+ // @var bool
'isFromTrustedProxy' => $request->isFromTrustedProxy(),
+ // @var array Request headers
'headers' => $request->headers->all(),
]);
}
diff --git a/src/app/Http/Controllers/API/V4/Admin/WalletsController.php b/src/app/Http/Controllers/API/V4/Admin/WalletsController.php
--- a/src/app/Http/Controllers/API/V4/Admin/WalletsController.php
+++ b/src/app/Http/Controllers/API/V4/Admin/WalletsController.php
@@ -37,10 +37,8 @@
*
* @param Request $request the API request
* @param string $id Wallet identifier
- *
- * @return JsonResponse The response
*/
- public function oneOff(Request $request, $id)
+ public function oneOff(Request $request, $id): JsonResponse
{
$wallet = Wallet::find($id);
$user = $this->guard()->user();
@@ -79,13 +77,12 @@
DB::commit();
- $response = [
+ return response()->json([
'status' => 'success',
'message' => self::trans("app.wallet-{$method}-success"),
+ // @var int Wallet balance (in cents)
'balance' => $wallet->balance,
- ];
-
- return response()->json($response);
+ ]);
}
/**
@@ -93,10 +90,8 @@
*
* @param Request $request the API request
* @param string $id Wallet identifier
- *
- * @return JsonResponse The response
*/
- public function update(Request $request, $id)
+ public function update(Request $request, $id): JsonResponse
{
$wallet = Wallet::find($id);
diff --git a/src/app/Http/Controllers/API/V4/AuthAttemptsController.php b/src/app/Http/Controllers/API/V4/AuthAttemptsController.php
--- a/src/app/Http/Controllers/API/V4/AuthAttemptsController.php
+++ b/src/app/Http/Controllers/API/V4/AuthAttemptsController.php
@@ -4,20 +4,20 @@
use App\AuthAttempt;
use App\Http\Controllers\Controller;
+use App\Http\Resources\AuthAttemptResource;
use App\Utils;
+use Dedoc\Scramble\Attributes\QueryParameter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class AuthAttemptsController extends Controller
{
/**
- * Confirm the authentication attempt.
+ * Confirm an authentication attempt.
*
- * @param string $id Id of AuthAttempt attempt
- *
- * @return JsonResponse
+ * @param string $id Authentication attempt identifier
*/
- public function confirm($id)
+ public function confirm($id): JsonResponse
{
$authAttempt = AuthAttempt::find($id);
if (!$authAttempt) {
@@ -31,17 +31,16 @@
\Log::debug("Confirm on {$authAttempt->id}");
$authAttempt->accept();
+
return response()->json([], 200);
}
/**
- * Deny the authentication attempt.
- *
- * @param string $id Id of AuthAttempt attempt
+ * Deny an authentication attempt.
*
- * @return JsonResponse
+ * @param string $id Authentication attempt identifier
*/
- public function deny($id)
+ public function deny($id): JsonResponse
{
$authAttempt = AuthAttempt::find($id);
if (!$authAttempt) {
@@ -55,17 +54,16 @@
\Log::debug("Deny on {$authAttempt->id}");
$authAttempt->deny();
+
return response()->json([], 200);
}
/**
- * Return details of authentication attempt.
- *
- * @param string $id Id of AuthAttempt attempt
+ * Authentication attempt information.
*
- * @return JsonResponse
+ * @param string $id Authentication attempt identifier
*/
- public function details($id)
+ public function details($id): JsonResponse
{
$authAttempt = AuthAttempt::find($id);
if (!$authAttempt) {
@@ -79,20 +77,23 @@
return response()->json([
'status' => 'success',
+ // User email address
'username' => $user->email,
+ // Country code (from the IP address of the authentication attempt)
'country' => Utils::countryForIP($authAttempt->ip),
- 'entry' => $authAttempt->toArray(),
+ // Authentication attempt information
+ 'entry' => new AuthAttemptResource($authAttempt),
]);
}
/**
- * Listing of client authAttempts.
- *
- * All authAttempt attempts from the current user
+ * List of authentication attempts.
*
- * @return JsonResponse
+ * All authentication attempts from the current user clients.
+ * The list page contains up to 10 entries.
*/
- public function index(Request $request)
+ #[QueryParameter('page', description: 'Page number', type: 'int', default: 1)]
+ public function index(Request $request): JsonResponse
{
$user = $this->guard()->user();
@@ -111,10 +112,8 @@
$hasMore = true;
}
- $result = $result->map(static function ($authAttempt) {
- return $authAttempt->toArray();
- });
+ // TODO: Change the response format to include 'list', 'count', 'hasMore' properties.
- return response()->json($result);
+ return response()->json(AuthAttemptResource::collection($result));
}
}
diff --git a/src/app/Http/Controllers/API/V4/CompanionAppsController.php b/src/app/Http/Controllers/API/V4/CompanionAppsController.php
--- a/src/app/Http/Controllers/API/V4/CompanionAppsController.php
+++ b/src/app/Http/Controllers/API/V4/CompanionAppsController.php
@@ -4,8 +4,10 @@
use App\CompanionApp;
use App\Http\Controllers\ResourceController;
+use App\Http\Resources\CompanionAppResource;
use App\Utils;
use BaconQrCode;
+use Dedoc\Scramble\Attributes\QueryParameter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
@@ -16,13 +18,11 @@
class CompanionAppsController extends ResourceController
{
/**
- * Remove the specified companion app.
+ * Remove a companion app.
*
* @param string $id Companion app identifier
- *
- * @return JsonResponse
*/
- public function destroy($id)
+ public function destroy($id): JsonResponse
{
$companion = CompanionApp::find($id);
if (!$companion) {
@@ -51,10 +51,8 @@
/**
* Create a companion app.
- *
- * @return JsonResponse
*/
- public function store(Request $request)
+ public function store(Request $request): JsonResponse
{
$user = $this->guard()->user();
@@ -77,18 +75,15 @@
return response()->json([
'status' => 'success',
'message' => self::trans('app.companion-create-success'),
+ // Companion app identifier
'id' => $app->id,
]);
}
/**
* Register a companion app.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function register(Request $request)
+ public function register(Request $request): JsonResponse
{
$user = $this->guard()->user();
@@ -150,14 +145,12 @@
}
/**
- * List devices.
- *
- * @return JsonResponse
+ * List companion apps.
*/
- public function index()
+ #[QueryParameter('page', description: 'Page number', type: 'int', default: 1)]
+ public function index(): JsonResponse
{
$user = $this->guard()->user();
- $search = trim(request()->input('search'));
$page = (int) (request()->input('page')) ?: 1;
$pageSize = 20;
$hasMore = false;
@@ -174,18 +167,12 @@
$hasMore = true;
}
- // Process the result
- $result = $result->map(
- static function ($device) {
- return array_merge($device->toArray(), [
- 'isReady' => $device->isPaired(),
- ]);
- }
- );
-
$result = [
- 'list' => $result,
+ // List of companion apps
+ 'list' => CompanionAppResource::collection($result),
+ // @var int Number of entries in the list
'count' => count($result),
+ // @var bool Indicates that there are more entries available
'hasMore' => $hasMore,
];
@@ -193,13 +180,11 @@
}
/**
- * Get the information about the specified companion app.
- *
- * @param string $id CompanionApp identifier
+ * Get companion app information.
*
- * @return JsonResponse
+ * @param string $id Companion app identifier
*/
- public function show($id)
+ public function show($id): CompanionAppResource|JsonResponse
{
$result = CompanionApp::find($id);
if (!$result) {
@@ -211,19 +196,15 @@
return $this->errorResponse(403);
}
- return response()->json(array_merge($result->toArray(), [
- 'statusInfo' => [
- 'isReady' => $result->isPaired(),
- ],
- ]));
+ return new CompanionAppResource($result);
}
/**
- * Retrieve the pairing information encoded into a qrcode image.
+ * Retrieve the pairing information encoded into a QR-code image.
*
- * @return JsonResponse
+ * @param string $id Companion app identifier
*/
- public function pairing($id)
+ public function pairing($id): JsonResponse
{
$result = CompanionApp::find($id);
if (!$result) {
@@ -255,13 +236,19 @@
}
$response = [
+ // Server URL
'serverUrl' => Utils::serviceUrl('', $user->tenant_id),
+ // Passport client identifier
'clientIdentifier' => $client->id,
+ // Client secret
'clientSecret' => $client->secret,
+ // Companion app identifier
'companionId' => $id,
+ // User email address
'username' => $user->email,
];
+ // TODO: Make it visible in API Docs
$response['qrcode'] = self::generateQRCode(json_encode($response));
return response()->json($response);
diff --git a/src/app/Http/Controllers/API/V4/ConfigController.php b/src/app/Http/Controllers/API/V4/ConfigController.php
--- a/src/app/Http/Controllers/API/V4/ConfigController.php
+++ b/src/app/Http/Controllers/API/V4/ConfigController.php
@@ -13,10 +13,8 @@
/**
* Get the per-user webmail configuration.
- *
- * @return JsonResponse The response
*/
- public function webmail(Request $request)
+ public function webmail(Request $request): JsonResponse
{
$user = $this->guard()->user();
@@ -25,7 +23,10 @@
}
$config = [
+ // @var array<string> Webmail configuration overlays
'kolab-configuration-overlays' => [],
+ // @var string|null Debug mode
+ 'debug' => null,
];
$skus = $user->skuTitles();
@@ -52,6 +53,11 @@
}
}
+ // TODO: Per-domain configuration, e.g. skin/logo
+ // $config['skin'] = 'apostrophy';
+ // $config['skin_logo'] = 'data:image/svg+xml;base64,'
+ // . base64_encode(file_get_contents(storage_path('logo.svg')));
+
if ($debug_setting = $user->settings()->where('key', 'debug')->first()) {
/** @var UserSetting $debug_setting */
// Make sure the setting didn't expire
@@ -62,11 +68,6 @@
}
}
- // TODO: Per-domain configuration, e.g. skin/logo
- // $config['skin'] = 'apostrophy';
- // $config['skin_logo'] = 'data:image/svg+xml;base64,'
- // . base64_encode(file_get_contents(storage_path('logo.svg')));
-
return response()->json($config);
}
}
diff --git a/src/app/Http/Controllers/API/V4/DeviceController.php b/src/app/Http/Controllers/API/V4/DeviceController.php
--- a/src/app/Http/Controllers/API/V4/DeviceController.php
+++ b/src/app/Http/Controllers/API/V4/DeviceController.php
@@ -13,10 +13,8 @@
* User claims the device ownership.
*
* @param string $hash Device secret identifier
- *
- * @return JsonResponse The response
*/
- public function claim(string $hash)
+ public function claim(string $hash): JsonResponse
{
if (strlen($hash) > 191) {
return $this->errorResponse(404);
@@ -41,11 +39,9 @@
*
* @param string $hash Device secret identifier
*
- * @return JsonResponse The response
- *
* @unauthenticated
*/
- public function info(string $hash)
+ public function info(string $hash): JsonResponse
{
if (strlen($hash) > 191) {
return $this->errorResponse(404);
diff --git a/src/app/Http/Controllers/API/V4/DomainsController.php b/src/app/Http/Controllers/API/V4/DomainsController.php
--- a/src/app/Http/Controllers/API/V4/DomainsController.php
+++ b/src/app/Http/Controllers/API/V4/DomainsController.php
@@ -7,6 +7,7 @@
use App\Jobs\Domain\CreateJob;
use App\Package;
use App\Rules\UserEmailDomain;
+use Dedoc\Scramble\Attributes\BodyParameter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -30,13 +31,11 @@
protected $relationArgs = [true, false];
/**
- * Confirm ownership of the specified domain (via DNS check).
+ * Confirm domain ownership (via DNS check).
*
* @param int $id Domain identifier
- *
- * @return JsonResponse|void
*/
- public function confirm($id)
+ public function confirm($id): JsonResponse
{
$domain = Domain::find($id);
@@ -63,13 +62,11 @@
}
/**
- * Remove the specified domain.
+ * Delete a domain.
*
* @param string $id Domain identifier
- *
- * @return JsonResponse
*/
- public function destroy($id)
+ public function destroy($id): JsonResponse
{
$domain = Domain::find($id);
@@ -97,10 +94,9 @@
/**
* Create a domain.
- *
- * @return JsonResponse
*/
- public function store(Request $request)
+ #[BodyParameter('package', description: 'SKU package identifier', type: 'string', required: true)]
+ public function store(Request $request): JsonResponse
{
$current_user = $this->guard()->user();
$wallet = $current_user->wallet();
@@ -113,6 +109,7 @@
$v = Validator::make(
$request->all(),
[
+ // Domain namespace
'namespace' => ['required', 'string', new UserEmailDomain()],
]
);
@@ -172,13 +169,11 @@
}
/**
- * Get the information about the specified domain.
+ * Domain information.
*
* @param string $id Domain identifier
- *
- * @return JsonResponse|void
*/
- public function show($id)
+ public function show($id): JsonResponse
{
$domain = Domain::find($id);
diff --git a/src/app/Http/Controllers/API/V4/FsController.php b/src/app/Http/Controllers/API/V4/FsController.php
--- a/src/app/Http/Controllers/API/V4/FsController.php
+++ b/src/app/Http/Controllers/API/V4/FsController.php
@@ -35,10 +35,8 @@
* Delete a file.
*
* @param string $id File identifier
- *
- * @return JsonResponse The response
*/
- public function destroy($id)
+ public function destroy($id): JsonResponse
{
// Only the file owner can do that, for now
$file = $this->inputItem($id, null);
@@ -267,10 +265,8 @@
/**
* Listing of files (and folders).
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$search = trim(request()->input('search'));
$page = (int) (request()->input('page')) ?: 1;
@@ -342,10 +338,8 @@
* Fetch the specific file metadata or content.
*
* @param string $id the file identifier
- *
- * @return JsonResponse|StreamedResponse
*/
- public function show($id)
+ public function show($id): JsonResponse|StreamedResponse
{
$file = $this->inputItem($id, self::READ);
diff --git a/src/app/Http/Controllers/API/V4/GroupsController.php b/src/app/Http/Controllers/API/V4/GroupsController.php
--- a/src/app/Http/Controllers/API/V4/GroupsController.php
+++ b/src/app/Http/Controllers/API/V4/GroupsController.php
@@ -10,6 +10,7 @@
use App\Rules\GroupName;
use App\Rules\UserEmailLocal;
use App\User;
+use Dedoc\Scramble\Attributes\BodyParameter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -76,12 +77,11 @@
/**
* Create a new group record.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function store(Request $request)
+ #[BodyParameter('name', description: 'Group name', type: 'string', required: true)]
+ #[BodyParameter('email', description: 'Group email address', type: 'string', required: true)]
+ #[BodyParameter('members', description: 'Member email addresses', type: 'array<string>', required: true)]
+ public function store(Request $request): JsonResponse
{
$current_user = $this->guard()->user();
$wallet = $current_user->wallet();
@@ -163,10 +163,10 @@
*
* @param Request $request the API request
* @param string $id Group identifier
- *
- * @return JsonResponse The response
*/
- public function update(Request $request, $id)
+ #[BodyParameter('name', description: 'Group name', type: 'string')]
+ #[BodyParameter('members', description: 'Member email addresses', type: 'array<string>', required: true)]
+ public function update(Request $request, $id): JsonResponse
{
$group = Group::find($id);
diff --git a/src/app/Http/Controllers/API/V4/HealthController.php b/src/app/Http/Controllers/API/V4/HealthController.php
--- a/src/app/Http/Controllers/API/V4/HealthController.php
+++ b/src/app/Http/Controllers/API/V4/HealthController.php
@@ -9,10 +9,8 @@
{
/**
* Liveness probe
- *
- * @return JsonResponse The response
*/
- public function liveness()
+ public function liveness(): JsonResponse
{
$response = response()->json('success', 200);
$response->noLogging = true; // @phpstan-ignore-line
@@ -21,10 +19,8 @@
/**
* Readiness probe
- *
- * @return JsonResponse The response
*/
- public function readiness()
+ public function readiness(): JsonResponse
{
$response = response()->json('success', 200);
$response->noLogging = true; // @phpstan-ignore-line
diff --git a/src/app/Http/Controllers/API/V4/LicenseController.php b/src/app/Http/Controllers/API/V4/LicenseController.php
--- a/src/app/Http/Controllers/API/V4/LicenseController.php
+++ b/src/app/Http/Controllers/API/V4/LicenseController.php
@@ -14,10 +14,8 @@
* Get the information on any license for the user.
*
* @param string $type License type
- *
- * @return JsonResponse The response
*/
- public function license(Request $request, string $type)
+ public function license(Request $request, string $type): JsonResponse
{
$user = $this->guard()->user();
@@ -58,7 +56,7 @@
return response()->json([
'status' => 'success',
- // @var array List of licenses (properties: key, type)
+ // @var array{'key': string, 'type': string} List of licenses
'list' => $licenses,
// @var int Number of entries in the list
'count' => count($licenses),
diff --git a/src/app/Http/Controllers/API/V4/MeetController.php b/src/app/Http/Controllers/API/V4/MeetController.php
--- a/src/app/Http/Controllers/API/V4/MeetController.php
+++ b/src/app/Http/Controllers/API/V4/MeetController.php
@@ -16,10 +16,8 @@
* joins (and effectively creates the session).
*
* @param string $id Room identifier (name)
- *
- * @return JsonResponse
*/
- public function joinRoom($id)
+ public function joinRoom($id): JsonResponse
{
$room = Room::where('name', $id)->first();
@@ -145,12 +143,8 @@
/**
* Webhook as triggered from the Meet server
- *
- * @param Request $request the API request
- *
- * @return Response The response
*/
- public function webhook(Request $request)
+ public function webhook(Request $request): Response
{
\Log::debug($request->getContent());
diff --git a/src/app/Http/Controllers/API/V4/MetricsController.php b/src/app/Http/Controllers/API/V4/MetricsController.php
--- a/src/app/Http/Controllers/API/V4/MetricsController.php
+++ b/src/app/Http/Controllers/API/V4/MetricsController.php
@@ -116,10 +116,8 @@
/**
* Expose swoole metrics
- *
- * @return Response The response
*/
- public function swooleMetrics()
+ public function swooleMetrics(): Response
{
$stats = app('Swoole\Http\Server')->stats();
// {"start_time":1750184075,"connection_num":8,"abort_count":0,"accept_count":13781,"close_count":13773,"worker_num":2,"task_worker_num":2,"user_worker_num":0,"idle_worker_num":0,"dispatch_count":13837,"request_count":13832,"response_count":13615,"total_recv_bytes":2898444,"total_send_bytes":30179791,"pipe_packet_msg_id":47769,"concurrency":2,"session_round":13781,"min_fd":22,"max_fd":32,"worker_request_count":646,"worker_response_count":635,"worker_dispatch_count":644,"worker_concurrency":1,"task_idle_worker_num":2,"tasking_num":0,"task_count":5505,"coroutine_num":0,"coroutine_peek_num":0}
@@ -160,10 +158,8 @@
/**
* Expose kolab metrics
- *
- * @return Response The response
*/
- public function metrics()
+ public function metrics(): Response
{
$appDomain = \config('app.domain');
$tenantId = \config('app.tenant_id');
diff --git a/src/app/Http/Controllers/API/V4/NGINXController.php b/src/app/Http/Controllers/API/V4/NGINXController.php
--- a/src/app/Http/Controllers/API/V4/NGINXController.php
+++ b/src/app/Http/Controllers/API/V4/NGINXController.php
@@ -114,12 +114,8 @@
/**
* Authentication request from the ngx_http_auth_request_module
- *
- * @param Request $request the API request
- *
- * @return Response The response
*/
- public function httpauth(Request $request)
+ public function httpauth(Request $request): Response
{
/*
* Php-Auth-Pw: simple123
@@ -163,12 +159,8 @@
/**
* Authentication request from the cyrus sasl
- *
- * @param Request $request the API request
- *
- * @return Response The response
*/
- public function cyrussasl(Request $request)
+ public function cyrussasl(Request $request): Response
{
$data = $request->getContent();
@@ -203,12 +195,8 @@
*
* @todo: Separate IMAP(+STARTTLS) from IMAPS, same for SMTP/submission. =>
* I suppose that's not necessary given that we have the information avialable in the headers?
- *
- * @param Request $request the API request
- *
- * @return Response The response
*/
- public function authenticate(Request $request)
+ public function authenticate(Request $request): Response
{
/*
* Auth-Login-Attempt: 1
@@ -251,12 +239,8 @@
/**
* Authentication request for roundcube imap.
- *
- * @param Request $request the API request
- *
- * @return Response The response
*/
- public function authenticateRoundcube(Request $request)
+ public function authenticateRoundcube(Request $request): Response
{
/*
* Auth-Login-Attempt: 1
@@ -301,10 +285,8 @@
* @param Request $request the API request
* @param bool $prefGuam whether or not Guam is enabled
* @param string $password the password to include in the response
- *
- * @return Response The response
*/
- private function authenticateIMAP(Request $request, $prefGuam, $password)
+ private function authenticateIMAP(Request $request, $prefGuam, $password): Response
{
if ($prefGuam) {
$port = \config('services.imap.guam_port');
@@ -329,10 +311,8 @@
*
* @param Request $request the API request
* @param string $password the password to include in the response
- *
- * @return Response The response
*/
- private function authenticateSMTP(Request $request, $password)
+ private function authenticateSMTP(Request $request, $password): Response
{
$response = response('')->withHeaders(
[
@@ -351,10 +331,8 @@
*
* @param Request $request the API request
* @param string $reason the reason for the failure
- *
- * @return Response The response
*/
- private function byebye(Request $request, $reason = null)
+ private function byebye(Request $request, $reason = null): Response
{
\Log::debug("Byebye: {$reason}");
diff --git a/src/app/Http/Controllers/API/V4/PackagesController.php b/src/app/Http/Controllers/API/V4/PackagesController.php
--- a/src/app/Http/Controllers/API/V4/PackagesController.php
+++ b/src/app/Http/Controllers/API/V4/PackagesController.php
@@ -10,10 +10,8 @@
{
/**
* Display a listing of packages.
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
// TODO: Packages should have an 'active' flag too, I guess
$response = [];
diff --git a/src/app/Http/Controllers/API/V4/PaymentsController.php b/src/app/Http/Controllers/API/V4/PaymentsController.php
--- a/src/app/Http/Controllers/API/V4/PaymentsController.php
+++ b/src/app/Http/Controllers/API/V4/PaymentsController.php
@@ -33,14 +33,10 @@
/**
* Create a new auto-payment mandate.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
#[BodyParameter('amount', description: 'Money amount', type: 'float', required: true)]
#[BodyParameter('balance', description: 'Wallet balance threshold', type: 'float', required: true)]
- public function mandateCreate(Request $request)
+ public function mandateCreate(Request $request): JsonResponse
{
$user = $this->guard()->user();
@@ -91,10 +87,8 @@
/**
* Revoke the auto-payment mandate.
- *
- * @return JsonResponse The response
*/
- public function mandateDelete()
+ public function mandateDelete(): JsonResponse
{
$user = $this->guard()->user();
@@ -115,14 +109,10 @@
/**
* Update a new auto-payment mandate.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
#[BodyParameter('amount', description: 'Money amount', type: 'float', required: true)]
#[BodyParameter('balance', description: 'Wallet balance threshold', type: 'float', required: true)]
- public function mandateUpdate(Request $request)
+ public function mandateUpdate(Request $request): JsonResponse
{
$user = $this->guard()->user();
@@ -158,12 +148,8 @@
/**
* Reset the auto-payment mandate, create a new payment for it.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function mandateReset(Request $request)
+ public function mandateReset(Request $request): JsonResponse
{
$user = $this->guard()->user();
@@ -241,10 +227,8 @@
/**
* Get status of the last payment.
- *
- * @return JsonResponse The response
*/
- public function paymentStatus()
+ public function paymentStatus(): JsonResponse
{
$user = $this->guard()->user();
$wallet = $user->wallets()->first();
@@ -279,12 +263,8 @@
/**
* Create a new payment.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function store(Request $request)
+ public function store(Request $request): JsonResponse
{
$user = $this->guard()->user();
@@ -341,10 +321,8 @@
* Update payment status (and balance).
*
* @param string $provider Provider name
- *
- * @return Response The response
*/
- public function webhook($provider)
+ public function webhook($provider): Response
{
$code = 200;
@@ -357,12 +335,8 @@
/**
* List payment methods.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function paymentMethods(Request $request)
+ public function paymentMethods(Request $request): JsonResponse
{
$user = $this->guard()->user();
@@ -376,12 +350,8 @@
/**
* Check for pending payments.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function hasPayments(Request $request)
+ public function hasPayments(Request $request): JsonResponse
{
$user = $this->guard()->user();
@@ -405,13 +375,9 @@
/**
* List pending payments.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
#[BodyParameter('page', description: 'List page', type: 'int')]
- public function payments(Request $request)
+ public function payments(Request $request): JsonResponse
{
$user = $this->guard()->user();
diff --git a/src/app/Http/Controllers/API/V4/PolicyController.php b/src/app/Http/Controllers/API/V4/PolicyController.php
--- a/src/app/Http/Controllers/API/V4/PolicyController.php
+++ b/src/app/Http/Controllers/API/V4/PolicyController.php
@@ -14,19 +14,18 @@
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
+use Symfony\Component\HttpFoundation\StreamedResponse;
class PolicyController extends Controller
{
/**
* Validate the password regarding the defined policies.
*
- * @return JsonResponse
- *
* @unauthenticated
*/
#[BodyParameter('user', description: 'User identifier', type: 'string')]
#[BodyParameter('password', description: 'User password', type: 'string', required: true)]
- public function checkPassword(Request $request)
+ public function checkPassword(Request $request): JsonResponse
{
$userId = $request->input('user');
$user = !empty($userId) ? User::find($userId) : null;
@@ -53,10 +52,8 @@
/**
* Take a greylist policy request
- *
- * @return JsonResponse
*/
- public function greylist()
+ public function greylist(): JsonResponse
{
$response = Greylist::handle(\request()->input());
@@ -66,10 +63,8 @@
/**
* Fetch the account policies for the current user account.
* The result includes all supported policy rules.
- *
- * @return JsonResponse
*/
- public function index(Request $request)
+ public function index(Request $request): JsonResponse
{
$user = $this->guard()->user();
@@ -113,22 +108,14 @@
/**
* SMTP Content Filter
- *
- * @param Request $request the API request
- *
- * @return Response The response
*/
- public function mailfilter(Request $request)
+ public function mailfilter(Request $request): Response|StreamedResponse
{
return Mailfilter::handle($request);
}
- /*
- * Apply a sensible rate limitation to a request.
- *
- * @return JsonResponse
- */
- public function ratelimit()
+ // Apply a sensible rate limitation to a request.
+ public function ratelimit(): JsonResponse
{
$response = RateLimit::handle(\request()->input());
@@ -137,34 +124,24 @@
/**
* Validate a mail reception request (includes greylisting)
- *
- * @return JsonResponse
*/
- public function reception()
+ public function reception(): JsonResponse
{
$response = SmtpAccess::reception(\request()->input());
return $response->jsonResponse();
}
- /*
- * Apply the sender policy framework to a request.
- *
- * @return JsonResponse
- */
- public function senderPolicyFramework()
+ // Apply the sender policy framework to a request.
+ public function senderPolicyFramework(): JsonResponse
{
$response = SPF::handle(\request()->input());
return $response->jsonResponse();
}
- /*
- * Validate sender/recipients in an SMTP submission request.
- *
- * @return JsonResponse
- */
- public function submission()
+ // Validate sender/recipients in an SMTP submission request.
+ public function submission(): JsonResponse
{
$response = SmtpAccess::submission(\request()->input());
diff --git a/src/app/Http/Controllers/API/V4/Reseller/DomainsController.php b/src/app/Http/Controllers/API/V4/Reseller/DomainsController.php
--- a/src/app/Http/Controllers/API/V4/Reseller/DomainsController.php
+++ b/src/app/Http/Controllers/API/V4/Reseller/DomainsController.php
@@ -10,10 +10,8 @@
{
/**
* Search for domains
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$search = trim(request()->input('search'));
$owner = trim(request()->input('owner'));
diff --git a/src/app/Http/Controllers/API/V4/Reseller/GroupsController.php b/src/app/Http/Controllers/API/V4/Reseller/GroupsController.php
--- a/src/app/Http/Controllers/API/V4/Reseller/GroupsController.php
+++ b/src/app/Http/Controllers/API/V4/Reseller/GroupsController.php
@@ -10,10 +10,8 @@
{
/**
* Search for groups
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$search = trim(request()->input('search'));
$owner = trim(request()->input('owner'));
diff --git a/src/app/Http/Controllers/API/V4/Reseller/InvitationsController.php b/src/app/Http/Controllers/API/V4/Reseller/InvitationsController.php
--- a/src/app/Http/Controllers/API/V4/Reseller/InvitationsController.php
+++ b/src/app/Http/Controllers/API/V4/Reseller/InvitationsController.php
@@ -12,10 +12,8 @@
{
/**
* Show the form for creating a new resource.
- *
- * @return JsonResponse
*/
- public function create()
+ public function create(): JsonResponse
{
return $this->errorResponse(404);
}
@@ -24,10 +22,8 @@
* Remove the specified invitation.
*
* @param int $id Invitation identifier
- *
- * @return JsonResponse
*/
- public function destroy($id)
+ public function destroy($id): JsonResponse
{
$invitation = SignupInvitation::withSubjectTenantContext()->find($id);
@@ -47,20 +43,16 @@
* Show the form for editing the specified resource.
*
* @param int $id Invitation identifier
- *
- * @return JsonResponse
*/
- public function edit($id)
+ public function edit($id): JsonResponse
{
return $this->errorResponse(404);
}
/**
* Display a listing of the resource.
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$pageSize = 10;
$search = request()->input('search');
@@ -104,10 +96,8 @@
* Resend the specified invitation.
*
* @param int $id Invitation identifier
- *
- * @return JsonResponse
*/
- public function resend($id)
+ public function resend($id): JsonResponse
{
$invitation = SignupInvitation::withSubjectTenantContext()->find($id);
@@ -130,10 +120,8 @@
/**
* Store a newly created resource in storage.
- *
- * @return JsonResponse
*/
- public function store(Request $request)
+ public function store(Request $request): JsonResponse
{
$errors = [];
$invitations = [];
@@ -216,10 +204,8 @@
* Display the specified resource.
*
* @param int $id Invitation identifier
- *
- * @return JsonResponse
*/
- public function show($id)
+ public function show($id): JsonResponse
{
return $this->errorResponse(404);
}
@@ -228,10 +214,8 @@
* Update the specified resource in storage.
*
* @param int $id
- *
- * @return JsonResponse
*/
- public function update(Request $request, $id)
+ public function update(Request $request, $id): JsonResponse
{
return $this->errorResponse(404);
}
diff --git a/src/app/Http/Controllers/API/V4/Reseller/ResourcesController.php b/src/app/Http/Controllers/API/V4/Reseller/ResourcesController.php
--- a/src/app/Http/Controllers/API/V4/Reseller/ResourcesController.php
+++ b/src/app/Http/Controllers/API/V4/Reseller/ResourcesController.php
@@ -10,10 +10,8 @@
{
/**
* Search for resources
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$search = trim(request()->input('search'));
$owner = trim(request()->input('owner'));
diff --git a/src/app/Http/Controllers/API/V4/Reseller/SharedFoldersController.php b/src/app/Http/Controllers/API/V4/Reseller/SharedFoldersController.php
--- a/src/app/Http/Controllers/API/V4/Reseller/SharedFoldersController.php
+++ b/src/app/Http/Controllers/API/V4/Reseller/SharedFoldersController.php
@@ -10,10 +10,8 @@
{
/**
* Search for shared folders
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$search = trim(request()->input('search'));
$owner = trim(request()->input('owner'));
diff --git a/src/app/Http/Controllers/API/V4/Reseller/UsersController.php b/src/app/Http/Controllers/API/V4/Reseller/UsersController.php
--- a/src/app/Http/Controllers/API/V4/Reseller/UsersController.php
+++ b/src/app/Http/Controllers/API/V4/Reseller/UsersController.php
@@ -4,6 +4,7 @@
use App\Domain;
use App\Group;
+use App\Http\Resources\UserResource;
use App\Resource;
use App\SharedFolder;
use App\SharedFolderAlias;
@@ -16,10 +17,8 @@
{
/**
* Searching of user accounts.
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$search = trim(request()->input('search'));
$owner = trim(request()->input('owner'));
@@ -105,16 +104,12 @@
}
}
- // Process the result
- $result = $result->map(
- function ($user) {
- return $this->objectToClient($user, true);
- }
- );
-
$result = [
- 'list' => $result,
+ // List of users
+ 'list' => UserResource::collection($result),
+ // @var int Number of entries in the list
'count' => count($result),
+ // @var string Response message
'message' => self::trans('app.search-foundxusers', ['x' => count($result)]),
];
diff --git a/src/app/Http/Controllers/API/V4/ResourcesController.php b/src/app/Http/Controllers/API/V4/ResourcesController.php
--- a/src/app/Http/Controllers/API/V4/ResourcesController.php
+++ b/src/app/Http/Controllers/API/V4/ResourcesController.php
@@ -48,10 +48,8 @@
* Create a new resource.
*
* @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function store(Request $request)
+ public function store(Request $request): JsonResponse
{
$current_user = $this->guard()->user();
$wallet = $current_user->wallet();
@@ -62,9 +60,13 @@
$domain = request()->input('domain');
- $rules = ['name' => ['required', 'string', new ResourceName($wallet->owner, $domain)]];
-
- $v = Validator::make($request->all(), $rules);
+ $v = Validator::make(
+ $request->all(),
+ [
+ // Resource name
+ 'name' => ['required', 'string', new ResourceName($wallet->owner, $domain)],
+ ]
+ );
if ($v->fails()) {
return response()->json(['status' => 'error', 'errors' => $v->errors()], 422);
@@ -93,10 +95,8 @@
*
* @param Request $request the API request
* @param string $id Resource identifier
- *
- * @return JsonResponse The response
*/
- public function update(Request $request, $id)
+ public function update(Request $request, $id): JsonResponse
{
$resource = Resource::find($id);
diff --git a/src/app/Http/Controllers/API/V4/RoomsController.php b/src/app/Http/Controllers/API/V4/RoomsController.php
--- a/src/app/Http/Controllers/API/V4/RoomsController.php
+++ b/src/app/Http/Controllers/API/V4/RoomsController.php
@@ -29,10 +29,8 @@
* Delete a room
*
* @param string $id Room identifier
- *
- * @return JsonResponse The response
*/
- public function destroy($id)
+ public function destroy($id): JsonResponse
{
$room = $this->inputRoom($id);
if (is_int($room)) {
@@ -49,10 +47,8 @@
/**
* List rooms.
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$user = $this->guard()->user();
@@ -91,10 +87,8 @@
* Set the room configuration.
*
* @param int|string $id Room identifier (or name)
- *
- * @return JsonResponse|void
*/
- public function setConfig($id)
+ public function setConfig($id): JsonResponse
{
$room = $this->inputRoom($id, Permission::ADMIN, $permission);
if (is_int($room)) {
@@ -124,10 +118,8 @@
* Get room information.
*
* @param string $id Room identifier
- *
- * @return JsonResponse
*/
- public function show($id)
+ public function show($id): JsonResponse
{
$room = $this->inputRoom($id, Permission::READ, $permission);
if (is_int($room)) {
@@ -169,10 +161,8 @@
* Get a list of SKUs available to the room.
*
* @param int $id Room identifier
- *
- * @return JsonResponse
*/
- public function skus($id)
+ public function skus($id): JsonResponse
{
$room = $this->inputRoom($id);
if (is_int($room)) {
@@ -186,10 +176,8 @@
* Create a new room.
*
* @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function store(Request $request)
+ public function store(Request $request): JsonResponse
{
$user = $this->guard()->user();
$wallet = $user->wallet();
@@ -231,10 +219,8 @@
*
* @param Request $request the API request
* @param string $id Room identifier
- *
- * @return JsonResponse The response
*/
- public function update(Request $request, $id)
+ public function update(Request $request, $id): JsonResponse
{
$room = $this->inputRoom($id, Permission::ADMIN);
if (is_int($room)) {
diff --git a/src/app/Http/Controllers/API/V4/SearchController.php b/src/app/Http/Controllers/API/V4/SearchController.php
--- a/src/app/Http/Controllers/API/V4/SearchController.php
+++ b/src/app/Http/Controllers/API/V4/SearchController.php
@@ -20,8 +20,6 @@
{
/**
* Find user's contacts
- *
- * @param Request $request the API request
*/
#[QueryParameter('search', description: 'Search string', type: 'string', required: true)]
#[QueryParameter('limit', description: 'Records limit', type: 'int', default: 15)]
@@ -72,15 +70,11 @@
/**
* Find user's email addresses
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
#[QueryParameter('search', description: 'Search string', type: 'string', required: true)]
#[QueryParameter('limit', description: 'Records limit', type: 'int', default: 15)]
#[QueryParameter('alias', description: 'Include aliases', type: 'bool')]
- public function searchSelf(Request $request)
+ public function searchSelf(Request $request): JsonResponse
{
$user = $this->guard()->user();
$search = trim($request->input('search'));
@@ -122,15 +116,11 @@
/**
* Find email addresses of all users (in an account)
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
#[QueryParameter('search', description: 'Search string', type: 'string', required: true)]
#[QueryParameter('limit', description: 'Records limit', type: 'int', default: 15)]
#[QueryParameter('alias', description: 'Include aliases', type: 'bool')]
- public function searchUser(Request $request)
+ public function searchUser(Request $request): JsonResponse
{
if (!\config('app.with_user_search')) {
return $this->errorResponse(404);
diff --git a/src/app/Http/Controllers/API/V4/SharedFoldersController.php b/src/app/Http/Controllers/API/V4/SharedFoldersController.php
--- a/src/app/Http/Controllers/API/V4/SharedFoldersController.php
+++ b/src/app/Http/Controllers/API/V4/SharedFoldersController.php
@@ -49,12 +49,8 @@
/**
* Create a new shared folder record.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function store(Request $request)
+ public function store(Request $request): JsonResponse
{
$current_user = $this->guard()->user();
$wallet = $current_user->wallet();
@@ -95,10 +91,8 @@
*
* @param Request $request the API request
* @param string $id Shared folder identifier
- *
- * @return JsonResponse The response
*/
- public function update(Request $request, $id)
+ public function update(Request $request, $id): JsonResponse
{
$folder = SharedFolder::find($id);
diff --git a/src/app/Http/Controllers/API/V4/SkusController.php b/src/app/Http/Controllers/API/V4/SkusController.php
--- a/src/app/Http/Controllers/API/V4/SkusController.php
+++ b/src/app/Http/Controllers/API/V4/SkusController.php
@@ -15,11 +15,9 @@
{
/**
* Get a list of active SKUs.
- *
- * @return JsonResponse
*/
#[QueryParameter('type', description: 'SKU type', type: 'string')]
- public function index()
+ public function index(): JsonResponse
{
$type = request()->input('type');
@@ -60,10 +58,8 @@
* Return SKUs available to the specified entitleable object.
*
* @param object $object Entitleable object
- *
- * @return JsonResponse
*/
- public static function objectSkus($object)
+ public static function objectSkus($object): JsonResponse
{
$response = [];
diff --git a/src/app/Http/Controllers/API/V4/SupportController.php b/src/app/Http/Controllers/API/V4/SupportController.php
--- a/src/app/Http/Controllers/API/V4/SupportController.php
+++ b/src/app/Http/Controllers/API/V4/SupportController.php
@@ -13,11 +13,9 @@
/**
* Submit support form.
*
- * @return JsonResponse
- *
* @unauthenticated
*/
- public function request(Request $request)
+ public function request(Request $request): JsonResponse
{
// Check required fields
$v = Validator::make($request->all(), $rules = [
diff --git a/src/app/Http/Controllers/API/V4/UsersController.php b/src/app/Http/Controllers/API/V4/UsersController.php
--- a/src/app/Http/Controllers/API/V4/UsersController.php
+++ b/src/app/Http/Controllers/API/V4/UsersController.php
@@ -8,8 +8,8 @@
use App\Http\Controllers\API\V4\User\DelegationTrait;
use App\Http\Controllers\RelationController;
use App\Http\Resources\UserInfoExtendedResource;
+use App\Http\Resources\UserResource;
use App\Jobs\User\CreateJob;
-use App\License;
use App\Package;
use App\Resource;
use App\Rules\Password;
@@ -18,6 +18,8 @@
use App\Sku;
use App\User;
use App\VerificationCode;
+use Dedoc\Scramble\Attributes\BodyParameter;
+use Dedoc\Scramble\Attributes\QueryParameter;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@@ -53,11 +55,12 @@
/**
* Listing of users.
*
- * The user-entitlements billed to the current user wallet(s)
- *
- * @return JsonResponse
+ * The list includes users billed to the current user wallet(s). It returns
+ * one page at a time. The page size is 20.
*/
- public function index()
+ #[QueryParameter('search', description: 'Search string', type: 'string')]
+ #[QueryParameter('page', description: 'Page number', type: 'int', default: 1)]
+ public function index(): JsonResponse
{
$user = $this->guard()->user();
$search = trim(request()->input('search'));
@@ -95,81 +98,18 @@
$hasMore = true;
}
- // Process the result
- $result = $result->map(
- function ($user) {
- return $this->objectToClient($user);
- }
- );
-
$result = [
- 'list' => $result,
- // @var int
+ // List of users
+ 'list' => UserResource::collection($result),
+ // @var int Number of entries in the list
'count' => count($result),
+ // @var bool Indicates that there are more entries available
'hasMore' => $hasMore,
];
return response()->json($result);
}
- /**
- * Get a license information.
- *
- * @param string $id The account to get licenses for
- * @param string $type License type
- *
- * @return JsonResponse The response
- */
- public function licenses(string $id, string $type)
- {
- $user = User::find($id);
-
- if (!$this->checkTenant($user)) {
- return $this->errorResponse(404);
- }
-
- if (!$this->guard()->user()->canRead($user)) {
- return $this->errorResponse(403);
- }
-
- $licenses = $user->licenses()->where('type', $type)->orderBy('created_at')->get();
-
- // No licenses for the user, take one if available
- if (!count($licenses)) {
- DB::beginTransaction();
-
- $license = License::withObjectTenantContext($user)
- ->where('type', $type)
- ->whereNull('user_id')
- ->limit(1)
- ->lockForUpdate()
- ->first();
-
- if ($license) {
- $license->user_id = $user->id;
- $license->save();
-
- $licenses = \collect([$license]);
- }
-
- DB::commit();
- }
-
- // Slim down the result set
- $licenses = $licenses->map(static function ($license) {
- return [
- 'key' => $license->key,
- 'type' => $license->type,
- ];
- });
-
- return response()->json([
- 'list' => $licenses,
- 'count' => count($licenses),
- 'hasMore' => false, // TODO
- ]);
- }
-
/**
* Webmail Login-As session initialization (via SSO)
*
@@ -177,10 +117,8 @@
* @param ServerRequestInterface $psrRequest PSR request
* @param Request $request The API request
* @param AuthorizationServer $server Authorization server
- *
- * @return JsonResponse
*/
- public function loginAs($id, ServerRequestInterface $psrRequest, Request $request, AuthorizationServer $server)
+ public function loginAs($id, ServerRequestInterface $psrRequest, Request $request, AuthorizationServer $server): JsonResponse
{
if (!\config('app.with_loginas')) {
return $this->errorResponse(404);
@@ -207,8 +145,6 @@
* User information.
*
* @param string $id The user identifier
- *
- * @return JsonResponse
*/
public function show($id)
{
@@ -222,9 +158,7 @@
return $this->errorResponse(403);
}
- $response = new UserInfoExtendedResource($user);
-
- return $response->response();
+ return new UserInfoExtendedResource($user);
}
/**
@@ -285,13 +219,23 @@
}
/**
- * Create a new user record.
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
+ * Create a new user.
*/
- public function store(Request $request)
+ #[BodyParameter('email', description: 'Email address', type: 'string', required: true)]
+ #[BodyParameter('package', description: 'SKU package identifier', type: 'string', required: true)]
+ #[BodyParameter('external_email', description: 'External email address', type: 'string')]
+ #[BodyParameter('phone', description: 'Phone number', type: 'string')]
+ #[BodyParameter('first_name', description: 'First name', type: 'string')]
+ #[BodyParameter('last_name', description: 'Last name', type: 'string')]
+ #[BodyParameter('organization', description: 'Organization name', type: 'string')]
+ #[BodyParameter('billing_address', description: 'Billing address', type: 'string')]
+ #[BodyParameter('country', description: 'Country code', type: 'string')]
+ #[BodyParameter('currency', description: 'Currency code', type: 'string')]
+ #[BodyParameter('password', description: 'New password', type: 'string')]
+ #[BodyParameter('password_confirmation', description: 'New password confirmation', type: 'string')]
+ #[BodyParameter('passwordLinkCode', description: 'Code for a by-link password reset', type: 'string')]
+ #[BodyParameter('aliases', description: 'Email address aliases', type: 'array<string>')]
+ public function store(Request $request): JsonResponse
{
$current_user = $this->guard()->user();
$wallet = $current_user->wallet();
@@ -302,8 +246,8 @@
$this->deleteBeforeCreate = null;
- if ($error_response = $this->validateUserRequest($request, null, $settings)) {
- return $error_response;
+ if ($errors = $this->validateUserRequest($request, null, $settings)) {
+ return response()->json(['status' => 'error', 'errors' => $errors], 422);
}
if (
@@ -358,10 +302,21 @@
*
* @param Request $request the API request
* @param string $id User identifier
- *
- * @return JsonResponse The response
*/
- public function update(Request $request, $id)
+ #[BodyParameter('external_email', description: 'External email address', type: 'string')]
+ #[BodyParameter('phone', description: 'Phone number', type: 'string')]
+ #[BodyParameter('first_name', description: 'First name', type: 'string')]
+ #[BodyParameter('last_name', description: 'Last name', type: 'string')]
+ #[BodyParameter('organization', description: 'Organization name', type: 'string')]
+ #[BodyParameter('billing_address', description: 'Billing address', type: 'string')]
+ #[BodyParameter('country', description: 'Country code', type: 'string')]
+ #[BodyParameter('currency', description: 'Currency code', type: 'string')]
+ #[BodyParameter('password', description: 'New password', type: 'string')]
+ #[BodyParameter('password_confirmation', description: 'New password confirmation', type: 'string')]
+ #[BodyParameter('passwordLinkCode', description: 'Code for a by-link password reset', type: 'string')]
+ #[BodyParameter('skus', description: 'Enabled SKUs', type: 'array')]
+ #[BodyParameter('aliases', description: 'Email address aliases', type: 'array<string>')]
+ public function update(Request $request, $id): JsonResponse
{
$user = User::find($id);
@@ -379,8 +334,8 @@
return $this->errorResponse(403);
}
- if ($error_response = $this->validateUserRequest($request, $user, $settings)) {
- return $error_response;
+ if ($errors = $this->validateUserRequest($request, $user, $settings)) {
+ return response()->json(['status' => 'error', 'errors' => $errors], 422);
}
DB::beginTransaction();
@@ -407,6 +362,8 @@
$response = [
'status' => 'success',
'message' => self::trans('app.user-update-success'),
+ // @var array Extended status/permissions information
+ 'statusInfo' => null,
];
// For self-update refresh the statusInfo in the UI
@@ -417,22 +374,6 @@
return response()->json($response);
}
- /**
- * Prepare user statuses for the UI
- *
- * @param User $user User object
- *
- * @return array Statuses array
- */
- public static function objectState($user): array
- {
- $state = parent::objectState($user);
-
- $state['isAccountDegraded'] = $user->isDegraded(true);
-
- return $state;
- }
-
/**
* Validate user input
*
@@ -440,9 +381,9 @@
* @param User|null $user User identifier
* @param array $settings User settings (from the request)
*
- * @return JsonResponse|null The error response on error
+ * @return array|null The error response on error
*/
- protected function validateUserRequest(Request $request, $user, &$settings = [])
+ protected function validateUserRequest(Request $request, $user, &$settings = []): ?array
{
$rules = [
'external_email' => 'nullable|email',
@@ -534,7 +475,7 @@
}
if (!empty($errors)) {
- return response()->json(['status' => 'error', 'errors' => $errors], 422);
+ return $errors;
}
// Update user settings
diff --git a/src/app/Http/Controllers/API/V4/VPNController.php b/src/app/Http/Controllers/API/V4/VPNController.php
--- a/src/app/Http/Controllers/API/V4/VPNController.php
+++ b/src/app/Http/Controllers/API/V4/VPNController.php
@@ -16,12 +16,8 @@
{
/**
* Token request from the vpn module
- *
- * @param Request $request the API request
- *
- * @return JsonResponse The response
*/
- public function token(Request $request)
+ public function token(Request $request): JsonResponse
{
$signingKey = \config("app.vpn.token_signing_key");
if (empty($signingKey)) {
diff --git a/src/app/Http/Controllers/API/V4/WalletsController.php b/src/app/Http/Controllers/API/V4/WalletsController.php
--- a/src/app/Http/Controllers/API/V4/WalletsController.php
+++ b/src/app/Http/Controllers/API/V4/WalletsController.php
@@ -96,11 +96,9 @@
* List receipts.
*
* @param string $id Wallet identifier
- *
- * @return JsonResponse
*/
#[QueryParameter('page', description: 'List page', type: 'int')]
- public function receipts($id)
+ public function receipts($id): JsonResponse
{
$wallet = Wallet::find($id);
@@ -160,10 +158,8 @@
* List active referral programs.
*
* @param string $id Wallet identifier
- *
- * @return JsonResponse
*/
- public function referralPrograms($id)
+ public function referralPrograms($id): JsonResponse
{
$wallet = Wallet::find($id);
@@ -223,12 +219,10 @@
* List transactions.
*
* @param string $id Wallet identifier
- *
- * @return JsonResponse
*/
#[QueryParameter('page', description: 'List page', type: 'int')]
#[QueryParameter('transaction', description: 'Parent transaction', type: 'string')]
- public function transactions($id)
+ public function transactions($id): JsonResponse
{
$wallet = Wallet::find($id);
diff --git a/src/app/Http/Controllers/ContentController.php b/src/app/Http/Controllers/ContentController.php
--- a/src/app/Http/Controllers/ContentController.php
+++ b/src/app/Http/Controllers/ContentController.php
@@ -38,10 +38,8 @@
* Get the list of FAQ entries for the specified page
*
* @param string $page Page path
- *
- * @return JsonResponse JSON response
*/
- public function faqContent(string $page)
+ public function faqContent(string $page): JsonResponse
{
if (empty($page)) {
return $this->errorResponse(404);
diff --git a/src/app/Http/Controllers/Controller.php b/src/app/Http/Controllers/Controller.php
--- a/src/app/Http/Controllers/Controller.php
+++ b/src/app/Http/Controllers/Controller.php
@@ -23,10 +23,8 @@
* @param int $code Error code
* @param string $message Error message
* @param array $data Additional response data
- *
- * @return JsonResponse
*/
- public static function errorResponse(int $code, string $message = '', array $data = [])
+ public static function errorResponse(int $code, string $message = '', array $data = []): JsonResponse
{
$errors = [
400 => "Bad request",
diff --git a/src/app/Http/Controllers/RelationController.php b/src/app/Http/Controllers/RelationController.php
--- a/src/app/Http/Controllers/RelationController.php
+++ b/src/app/Http/Controllers/RelationController.php
@@ -2,11 +2,13 @@
namespace App\Http\Controllers;
+use App\Enums\ProcessState;
use App\Group;
use App\Resource;
use App\SharedFolder;
use App\User;
use Carbon\Carbon;
+use Dedoc\Scramble\Attributes\QueryParameter;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Str;
@@ -31,10 +33,8 @@
* Delete a resource.
*
* @param string $id Resource identifier
- *
- * @return JsonResponse The response
*/
- public function destroy($id)
+ public function destroy($id): JsonResponse
{
$resource = $this->model::find($id);
@@ -80,10 +80,8 @@
* List resources.
*
* The resource entitlements billed to the current user wallet(s)
- *
- * @return JsonResponse
*/
- public function index()
+ public function index(): JsonResponse
{
$user = $this->guard()->user();
@@ -236,17 +234,20 @@
return $v['state'];
}));
- $state = $all === $checked ? 'done' : 'running';
+ $state = $all === $checked ? ProcessState::Done : ProcessState::Running;
// After 180 seconds assume the process is in failed state,
// this should unlock the Refresh button in the UI
if ($all !== $checked && $object->created_at->diffInSeconds(Carbon::now()) > 180) {
- $state = 'failed';
+ $state = ProcessState::Failed;
}
return [
+ // @var array<array{'label': string, 'title': string, 'state': bool, 'link': string}> Process information
'process' => $process,
+ // @var ProcessState Current process state
'processState' => $state,
+ // @var bool Indicates that the process ended successfully
'isDone' => $all === $checked,
];
}
@@ -296,7 +297,7 @@
$response['message'] = self::trans('app.process-' . $suffix);
if ($async && !$success) {
- $response['processState'] = 'waiting';
+ $response['processState'] = ProcessState::Waiting;
$response['status'] = 'success';
$response['message'] = self::trans('app.process-async');
}
@@ -309,10 +310,8 @@
* Set the resource configuration.
*
* @param int $id Resource identifier
- *
- * @return JsonResponse
*/
- public function setConfig($id)
+ public function setConfig($id): JsonResponse
{
$resource = $this->model::find($id);
@@ -333,7 +332,7 @@
$errors = $resource->setConfig(request()->input());
if (!empty($errors)) {
- return response()->json(['status' => 'error', 'errors' => $errors], 422);
+ return response()->json(['status' => 'error', /* @var array */ 'errors' => $errors], 422);
}
return response()->json([
@@ -346,8 +345,6 @@
* Get resource information
*
* @param string $id Resource identifier
- *
- * @return JsonResponse
*/
public function show($id)
{
@@ -388,10 +385,8 @@
* Get a list of SKUs available to the resource.
*
* @param int $id Resource identifier
- *
- * @return JsonResponse
*/
- public function skus($id)
+ public function skus($id): JsonResponse
{
$resource = $this->model::find($id);
@@ -407,13 +402,12 @@
}
/**
- * Fetch resource status (and reload setup process)
+ * Get status (and reload setup process)
*
* @param int $id Resource identifier
- *
- * @return JsonResponse
*/
- public function status($id)
+ #[QueryParameter('refresh', description: 'Trigger a refresh (push the process forward)', type: 'bool')]
+ public function status($id): JsonResponse
{
$resource = $this->model::find($id);
diff --git a/src/app/Http/Controllers/ResourceController.php b/src/app/Http/Controllers/ResourceController.php
--- a/src/app/Http/Controllers/ResourceController.php
+++ b/src/app/Http/Controllers/ResourceController.php
@@ -62,8 +62,6 @@
* Display information of a resource specified by $id.
*
* @param string $id the resource to show information for
- *
- * @return JsonResponse
*/
#[ExcludeRouteFromDocs]
public function show($id)
diff --git a/src/app/Http/Controllers/WellKnownController.php b/src/app/Http/Controllers/WellKnownController.php
--- a/src/app/Http/Controllers/WellKnownController.php
+++ b/src/app/Http/Controllers/WellKnownController.php
@@ -8,10 +8,8 @@
{
/**
* Return the mtaSts policy
- *
- * @return Response The response
*/
- public function mtaSts()
+ public function mtaSts(): Response
{
$policy = \config('app.mta_sts');
diff --git a/src/app/Http/Resources/AuthAttemptResource.php b/src/app/Http/Resources/AuthAttemptResource.php
new file mode 100644
--- /dev/null
+++ b/src/app/Http/Resources/AuthAttemptResource.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace App\Http\Resources;
+
+use App\AuthAttempt;
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+
+/**
+ * AuthAttempt response
+ *
+ * @mixin AuthAttempt
+ */
+class AuthAttemptResource extends JsonResource
+{
+ /**
+ * Transform the resource into an array.
+ */
+ public function toArray(Request $request): array
+ {
+ return [
+ // TODO: Do we need all properties?
+ // TODO: Document properties for Scramble
+ $this->merge(parent::toArray($request)),
+ ];
+ }
+}
diff --git a/src/app/Http/Resources/CompanionAppResource.php b/src/app/Http/Resources/CompanionAppResource.php
new file mode 100644
--- /dev/null
+++ b/src/app/Http/Resources/CompanionAppResource.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace App\Http\Resources;
+
+use App\CompanionApp;
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+
+/**
+ * CompanionApp response
+ *
+ * @mixin CompanionApp
+ */
+class CompanionAppResource extends JsonResource
+{
+ /**
+ * Transform the resource into an array.
+ */
+ public function toArray(Request $request): array
+ {
+ return [
+ $this->merge(parent::toArray($request)),
+ // @var bool Indicates the app status
+ 'isReady' => $this->resource->isPaired(),
+ ];
+ }
+}
diff --git a/src/app/Http/Resources/UserInfoResource.php b/src/app/Http/Resources/UserInfoResource.php
--- a/src/app/Http/Resources/UserInfoResource.php
+++ b/src/app/Http/Resources/UserInfoResource.php
@@ -7,14 +7,11 @@
use App\Providers\PaymentProvider;
use App\User;
use Illuminate\Http\Request;
-use Illuminate\Http\Resources\Json\JsonResource;
/**
* User information response
- *
- * @mixin User
*/
-class UserInfoResource extends JsonResource
+class UserInfoResource extends UserResource
{
/** @const array List of user setting keys available for modification in UI */
public const USER_SETTINGS = [
@@ -43,7 +40,6 @@
$settings = $this->resource->settings()->whereIn('key', $keys)->pluck('value', 'key')->all();
// Status info
- $state = UsersController::objectState($this->resource);
$statusInfo = UsersController::statusInfo($this->resource);
// Information about wallets and accounts for access checks
@@ -52,37 +48,10 @@
$wallet = $this->walletPropsMap($wallet);
return [
- // User identifier
- 'id' => $this->resource->id,
- // User email address
- 'email' => $this->resource->email,
- // User status
- 'status' => $this->resource->status,
- // User creation date-time
- 'created_at' => (string) $this->resource->created_at,
- // User deletion date-time
- 'deleted_at' => (string) $this->resource->deleted_at,
-
- // @var bool Is user active?
- 'isActive' => $state['isActive'] ?? false,
- // @var bool Is user deleted?
- 'isDeleted' => $state['isDeleted'] ?? false,
- // @var bool Is user degraded?
- 'isDegraded' => $state['isDegraded'] ?? false,
- // @var bool Is account owner degraded?
- 'isAccountDegraded' => $state['isAccountDegraded'] ?? false,
- // @var bool Readiness state
- 'isReady' => $state['isReady'],
- // @var bool IMAP readiness state
- 'isImapReady' => $state['isImapReady'] ?? false,
- // @var bool LDAP readiness state
- 'isLdapReady' => $this->when(isset($state['isLdapReady']), $state['isLdapReady'] ?? false),
+ $this->merge(parent::toArray($request)),
+
// @var bool Is user locked?
'isLocked' => $isLocked,
- // @var bool Is user restricted?
- 'isRestricted' => $state['isRestricted'] ?? false,
- // @var bool Is user suspended?
- 'isSuspended' => $state['isSuspended'] ?? false,
// @var array<strig, mixed> User settings (first_name, last_name, phone, etc.)
'settings' => $settings,
diff --git a/src/app/Http/Resources/UserResource.php b/src/app/Http/Resources/UserResource.php
new file mode 100644
--- /dev/null
+++ b/src/app/Http/Resources/UserResource.php
@@ -0,0 +1,66 @@
+<?php
+
+namespace App\Http\Resources;
+
+use App\Http\Controllers\RelationController;
+use App\User;
+use Illuminate\Http\Request;
+use Illuminate\Http\Resources\Json\JsonResource;
+use Illuminate\Support\Facades\Auth;
+
+/**
+ * User response
+ *
+ * @mixin User
+ */
+class UserResource extends JsonResource
+{
+ /**
+ * Transform the resource into an array.
+ */
+ public function toArray(Request $request): array
+ {
+ $actor = Auth::guard()->user();
+ $isAdmin = $actor && in_array($actor->role, [User::ROLE_ADMIN, User::ROLE_RESELLER]);
+
+ $state = RelationController::objectState($this->resource);
+
+ return [
+ // User identifier
+ 'id' => $this->resource->id,
+ // User email address
+ 'email' => $this->resource->email,
+ // User status
+ 'status' => $this->resource->status,
+
+ $this->mergeWhen($isAdmin, [
+ // User creation date-time
+ 'created_at' => (string) $this->resource->created_at,
+ // User deletion date-time
+ 'deleted_at' => (string) $this->resource->deleted_at,
+ ]),
+
+ // @var bool Is user active?
+ 'isActive' => $state['isActive'] ?? false,
+ // @var bool Is user deleted?
+ 'isDeleted' => $state['isDeleted'] ?? false,
+ // @var bool Is user degraded?
+ 'isDegraded' => $state['isDegraded'] ?? false,
+ // @var bool Readiness state
+ 'isReady' => $state['isReady'],
+ // @var bool IMAP readiness state
+ 'isImapReady' => $state['isImapReady'] ?? false,
+ // @var bool LDAP readiness state
+ 'isLdapReady' => $this->when(isset($state['isLdapReady']), $state['isLdapReady'] ?? false),
+ // @var bool Is user restricted?
+ 'isRestricted' => $state['isRestricted'] ?? false,
+ // @var bool Is user suspended?
+ 'isSuspended' => $state['isSuspended'] ?? false,
+
+ // @var bool Is account owner degraded?
+ 'isAccountDegraded' => $this->resource->isDegraded(true),
+ // TODO: Above property is a performance issue in users list context
+ // It probably should be moved to UserInfoResource, but carefully
+ ];
+ }
+}
diff --git a/src/app/Providers/AppServiceProvider.php b/src/app/Providers/AppServiceProvider.php
--- a/src/app/Providers/AppServiceProvider.php
+++ b/src/app/Providers/AppServiceProvider.php
@@ -162,6 +162,9 @@
// For Scramble (API documentation) we replace external js/css resources with locally stored
if (str_starts_with(\request()->path(), 'docs/api')) {
if (preg_match_all('~(src|href)="(https://unpkg.com/[^"]+)~', $str, $matches)) {
+ if (!file_exists(\public_path('vendor'))) {
+ mkdir(\public_path('vendor'));
+ }
if (!file_exists(\public_path('vendor/scramble'))) {
mkdir(\public_path('vendor/scramble'));
}
diff --git a/src/resources/vue/CompanionApp/Info.vue b/src/resources/vue/CompanionApp/Info.vue
--- a/src/resources/vue/CompanionApp/Info.vue
+++ b/src/resources/vue/CompanionApp/Info.vue
@@ -47,7 +47,6 @@
<script>
import ListInput from '../Widgets/ListInput'
import ModalDialog from '../Widgets/ModalDialog'
- import StatusComponent from '../Widgets/Status'
import SubscriptionSelect from '../Widgets/SubscriptionSelect'
import { library } from '@fortawesome/fontawesome-svg-core'
@@ -61,7 +60,6 @@
components: {
ListInput,
ModalDialog,
- StatusComponent,
SubscriptionSelect
},
beforeRouteUpdate (to, from, next) {
@@ -76,7 +74,6 @@
companion_id: null,
companion: {},
qrcode: "",
- status: {}
}
},
created() {
@@ -85,7 +82,6 @@
axios.get('/api/v4/companions/' + this.companion_id, { loader: true })
.then(response => {
this.companion = response.data
- this.status = response.data.statusInfo
})
.catch(this.$root.errorHandler)
@@ -108,9 +104,6 @@
}
})
},
- statusUpdate(companion) {
- this.companion = Object.assign({}, this.companion, companion)
- },
submit() {
this.$root.clearFormValidation($('#general form'))
diff --git a/src/routes/api.php b/src/routes/api.php
--- a/src/routes/api.php
+++ b/src/routes/api.php
@@ -47,8 +47,7 @@
Route::group(
[
- 'domain' => \config('app.website_domain'),
- 'middleware' => ['auth:api', 'scope:mfa,api'],
+ 'middleware' => ['regularHosts', 'auth:api', 'scope:mfa,api'],
'prefix' => 'v4',
],
static function () {
diff --git a/src/tests/Browser/Reseller/UserTest.php b/src/tests/Browser/Reseller/UserTest.php
--- a/src/tests/Browser/Reseller/UserTest.php
+++ b/src/tests/Browser/Reseller/UserTest.php
@@ -553,7 +553,7 @@
$browser->with(new Dropdown('h1 div.dropdown'), static function (Browser $browser) {
$browser->assertButton('Actions', 'btn-outline-primary')
->clickDropdownItem('#button-unsuspend', 'Unsuspend');
- })
+ })
->with(new Dialog('#suspend-dialog'), static function (Browser $browser) {
$browser->assertSeeIn('@title', 'Unsuspend')
->assertSeeIn('@button-cancel', 'Cancel')
diff --git a/src/tests/Feature/Controller/ConfigTest.php b/src/tests/Feature/Controller/ConfigTest.php
--- a/src/tests/Feature/Controller/ConfigTest.php
+++ b/src/tests/Feature/Controller/ConfigTest.php
@@ -25,7 +25,7 @@
$json = $response->json();
$this->assertSame(['kolab4', 'groupware'], $json['kolab-configuration-overlays']);
- $this->assertArrayNotHasKey('debug', $json);
+ $this->assertNull($json['debug']);
// Ned has groupware, activesync and 2FA
$response = $this->actingAs($ned)->get('api/v4/config/webmail');
@@ -54,7 +54,7 @@
$json = $response->json();
- $this->assertArrayNotHasKey('debug', $json);
+ $this->assertNull($json['debug']);
$this->assertNull($joe->getSetting('debug'));
}
}
diff --git a/src/tests/Feature/Controller/GroupsTest.php b/src/tests/Feature/Controller/GroupsTest.php
--- a/src/tests/Feature/Controller/GroupsTest.php
+++ b/src/tests/Feature/Controller/GroupsTest.php
@@ -3,6 +3,7 @@
namespace Tests\Feature\Controller;
use App\Domain;
+use App\Enums\ProcessState;
use App\Group;
use App\Http\Controllers\API\V4\GroupsController;
use App\User;
@@ -405,7 +406,7 @@
$this->assertSame('running', $result['processState']);
} else {
$this->assertTrue($result['isDone']);
- $this->assertSame('done', $result['processState']);
+ $this->assertSame(ProcessState::Done, $result['processState']);
$this->markTestSkipped();
}
@@ -414,7 +415,7 @@
$result = GroupsController::statusInfo($group);
- $this->assertSame('failed', $result['processState']);
+ $this->assertSame(ProcessState::Failed, $result['processState']);
$group->status |= Group::STATUS_LDAP_READY;
$group->save();
@@ -427,7 +428,7 @@
$this->assertTrue($result['process'][0]['state']);
$this->assertSame('distlist-ldap-ready', $result['process'][1]['label']);
$this->assertTrue($result['process'][2]['state']);
- $this->assertSame('done', $result['processState']);
+ $this->assertSame(ProcessState::Done, $result['processState']);
}
/**
diff --git a/src/tests/Feature/Controller/ResourcesTest.php b/src/tests/Feature/Controller/ResourcesTest.php
--- a/src/tests/Feature/Controller/ResourcesTest.php
+++ b/src/tests/Feature/Controller/ResourcesTest.php
@@ -3,6 +3,7 @@
namespace Tests\Feature\Controller;
use App\Domain;
+use App\Enums\ProcessState;
use App\Http\Controllers\API\V4\ResourcesController;
use App\Jobs\Resource\CreateJob;
use App\Resource;
@@ -335,7 +336,7 @@
}
$this->assertTrue(empty($json['status']));
$this->assertTrue(empty($json['message']));
- $this->assertSame('running', $json['processState']);
+ $this->assertSame(ProcessState::Running->value, $json['processState']);
// Make sure the domain is confirmed (other test might unset that status)
$domain = $this->getTestDomain('kolab.org');
@@ -361,7 +362,7 @@
$this->assertSame('resource-imap-ready', $json['process'][2]['label']);
$this->assertTrue($json['process'][2]['state']);
$this->assertSame('Setup process has been pushed. Please wait.', $json['message']);
- $this->assertSame('waiting', $json['processState']);
+ $this->assertSame(ProcessState::Waiting->value, $json['processState']);
Queue::assertPushed(CreateJob::class, 1);
} else {
@@ -369,7 +370,7 @@
$this->assertSame('resource-imap-ready', $json['process'][1]['label']);
$this->assertTrue($json['process'][1]['state']);
$this->assertSame('Setup process finished successfully.', $json['message']);
- $this->assertSame('done', $json['processState']);
+ $this->assertSame(ProcessState::Done->value, $json['processState']);
}
// Test a case when a domain is not ready
@@ -389,13 +390,13 @@
$this->assertSame('resource-ldap-ready', $json['process'][1]['label']);
$this->assertFalse($json['process'][1]['state']);
$this->assertSame('Setup process has been pushed. Please wait.', $json['message']);
- $this->assertSame('waiting', $json['processState']);
+ $this->assertSame(ProcessState::Waiting->value, $json['processState']);
Queue::assertPushed(CreateJob::class, 1);
} else {
$this->assertSame('Setup process finished successfully.', $json['message']);
$this->assertTrue($json['isReady']);
- $this->assertSame('done', $json['processState']);
+ $this->assertSame(ProcessState::Done->value, $json['processState']);
}
}
@@ -427,14 +428,14 @@
$this->assertSame('resource-imap-ready', $result['process'][1]['label']);
$this->assertFalse($result['process'][1]['state']);
}
- $this->assertSame('running', $result['processState']);
+ $this->assertSame(ProcessState::Running, $result['processState']);
$resource->created_at = Carbon::now()->subSeconds(181);
$resource->save();
$result = ResourcesController::statusInfo($resource);
- $this->assertSame('failed', $result['processState']);
+ $this->assertSame(ProcessState::Failed, $result['processState']);
$resource->status |= Resource::STATUS_LDAP_READY | Resource::STATUS_IMAP_READY;
$resource->save();
@@ -453,7 +454,7 @@
$this->assertSame('resource-imap-ready', $result['process'][1]['label']);
$this->assertTrue($result['process'][1]['state']);
}
- $this->assertSame('done', $result['processState']);
+ $this->assertSame(ProcessState::Done, $result['processState']);
}
/**
diff --git a/src/tests/Feature/Controller/SharedFoldersTest.php b/src/tests/Feature/Controller/SharedFoldersTest.php
--- a/src/tests/Feature/Controller/SharedFoldersTest.php
+++ b/src/tests/Feature/Controller/SharedFoldersTest.php
@@ -3,6 +3,7 @@
namespace Tests\Feature\Controller;
use App\Domain;
+use App\Enums\ProcessState;
use App\Http\Controllers\API\V4\SharedFoldersController;
use App\Jobs\SharedFolder\CreateJob;
use App\SharedFolder;
@@ -325,7 +326,7 @@
$this->assertFalse($json['isReady']);
$this->assertFalse($json['isDeleted']);
$this->assertTrue($json['isActive']);
- $this->assertSame('running', $json['processState']);
+ $this->assertSame(ProcessState::Running->value, $json['processState']);
$this->assertTrue(empty($json['status']));
$this->assertTrue(empty($json['message']));
$this->assertSame('shared-folder-new', $json['process'][0]['label']);
@@ -362,7 +363,7 @@
$this->assertSame('shared-folder-imap-ready', $json['process'][2]['label']);
$this->assertTrue($json['process'][2]['state']);
$this->assertSame('Setup process has been pushed. Please wait.', $json['message']);
- $this->assertSame('waiting', $json['processState']);
+ $this->assertSame(ProcessState::Waiting->value, $json['processState']);
Queue::assertPushed(CreateJob::class, 1);
} else {
@@ -370,7 +371,7 @@
$this->assertSame('shared-folder-imap-ready', $json['process'][1]['label']);
$this->assertTrue($json['process'][1]['state']);
$this->assertSame('Setup process finished successfully.', $json['message']);
- $this->assertSame('done', $json['processState']);
+ $this->assertSame(ProcessState::Done->value, $json['processState']);
}
$this->assertSame('success', $json['status']);
@@ -398,7 +399,7 @@
$this->assertTrue($json['isReady']);
$this->assertSame('shared-folder-imap-ready', $json['process'][1]['label']);
$this->assertTrue($json['process'][1]['state']);
- $this->assertSame('done', $json['processState']);
+ $this->assertSame(ProcessState::Done->value, $json['processState']);
}
}
@@ -419,7 +420,7 @@
$result = SharedFoldersController::statusInfo($folder);
$this->assertFalse($result['isDone']);
- $this->assertSame('running', $result['processState']);
+ $this->assertSame(ProcessState::Running, $result['processState']);
$this->assertSame('shared-folder-new', $result['process'][0]['label']);
$this->assertTrue($result['process'][0]['state']);
if (\config('app.with_ldap')) {
@@ -432,7 +433,7 @@
$result = SharedFoldersController::statusInfo($folder);
- $this->assertSame('failed', $result['processState']);
+ $this->assertSame(ProcessState::Failed, $result['processState']);
$folder->status |= SharedFolder::STATUS_LDAP_READY | SharedFolder::STATUS_IMAP_READY;
$folder->save();
@@ -440,7 +441,7 @@
$result = SharedFoldersController::statusInfo($folder);
$this->assertTrue($result['isDone']);
- $this->assertSame('done', $result['processState']);
+ $this->assertSame(ProcessState::Done, $result['processState']);
$this->assertSame('shared-folder-new', $result['process'][0]['label']);
$this->assertTrue($result['process'][0]['state']);
if (\config('app.with_ldap')) {
diff --git a/src/tests/Feature/Controller/UsersTest.php b/src/tests/Feature/Controller/UsersTest.php
--- a/src/tests/Feature/Controller/UsersTest.php
+++ b/src/tests/Feature/Controller/UsersTest.php
@@ -4,6 +4,7 @@
use App\Discount;
use App\Domain;
+use App\Enums\ProcessState;
use App\Http\Controllers\API\V4\UsersController;
use App\Http\Resources\UserInfoResource;
use App\Jobs\User\CreateJob;
@@ -599,7 +600,7 @@
}
$this->assertSame('user-new', $result['process'][0]['label']);
$this->assertTrue($result['process'][0]['state']);
- $this->assertSame('running', $result['processState']);
+ $this->assertSame(ProcessState::Running, $result['processState']);
$this->assertTrue($result['enableRooms']);
$this->assertFalse($result['enableBeta']);
@@ -608,7 +609,7 @@
$result = UsersController::statusInfo($user);
- $this->assertSame('failed', $result['processState']);
+ $this->assertSame(ProcessState::Failed, $result['processState']);
$user->status |= User::STATUS_LDAP_READY | User::STATUS_IMAP_READY;
$user->save();
@@ -616,7 +617,7 @@
$result = UsersController::statusInfo($user);
$this->assertTrue($result['isDone']);
- $this->assertSame('done', $result['processState']);
+ $this->assertSame(ProcessState::Done, $result['processState']);
if (\config('app.with_ldap')) {
$this->assertCount(3, $result['process']);
$this->assertSame('user-ldap-ready', $result['process'][1]['label']);
@@ -1427,7 +1428,7 @@
$wallet->setSettings(['mollie_id' => null, 'stripe_id' => null]);
$wallet->owner->setSettings(['plan_id' => null]);
- $result = (new UserInfoResource($john))->toArray(\request());
+ $result = (array) (new UserInfoResource($john))->response()->getData(true);
$this->assertSame($john->id, $result['id']);
$this->assertSame($john->email, $result['email']);
@@ -1463,7 +1464,7 @@
$ned = $this->getTestUser('ned@kolab.org');
$ned_wallet = $ned->wallets()->first();
- $result = (new UserInfoResource($ned))->toArray(\request());
+ $result = (array) (new UserInfoResource($ned))->response()->getData(true);
$this->assertSame($ned->id, $result['id']);
$this->assertSame($ned->email, $result['email']);
@@ -1495,7 +1496,7 @@
$wallet->setSetting($mod_provider . '_id', 123);
$john->refresh();
- $result = (new UserInfoResource($john))->toArray(\request());
+ $result = (array) (new UserInfoResource($john))->response()->getData(true);
$this->assertSame($john->id, $result['id']);
$this->assertSame($discount->id, $result['wallet']['discount_id']);
@@ -1513,7 +1514,7 @@
$jack->status |= User::STATUS_ACTIVE;
$jack->save();
- $result = (new UserInfoResource($jack))->toArray(\request());
+ $result = (array) (new UserInfoResource($jack))->response()->getData(true);
$this->assertFalse($result['statusInfo']['enableDomains']);
$this->assertFalse($result['statusInfo']['enableWallets']);
@@ -1529,7 +1530,7 @@
$john->status &= ~User::STATUS_ACTIVE;
$john->save();
- $result = (new UserInfoResource($john))->toArray(\request());
+ $result = (array) (new UserInfoResource($john))->response()->getData(true);
$this->assertTrue($result['isLocked']);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 3, 3:58 PM (20 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18823520
Default Alt Text
D5577.1775231910.diff (114 KB)

Event Timeline