Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117766096
D5577.1775231910.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
114 KB
Referenced Files
None
Subscribers
None
D5577.1775231910.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D5577: More API docs - refactoring and cleanup
Attached
Detach File
Event Timeline