Files
cattr/app/Http/Controllers/Api/UserController.php
Noor E Ilahi 7ccf44f7da first commit
2026-01-09 12:54:53 +05:30

571 lines
22 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Http\Controllers\Api;
use App;
use App\Enums\Role;
use App\Enums\ScreenshotsState;
use App\Http\Requests\User\ListUsersRequest;
use App\Scopes\UserAccessScope;
use Settings;
use Carbon\Carbon;
use Exception;
use Filter;
use App\Mail\UserCreated;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use CatEvent;
use Mail;
use App\Http\Requests\User\CreateUserRequest;
use App\Http\Requests\User\EditUserRequest;
use App\Http\Requests\User\SendInviteUserRequest;
use App\Http\Requests\User\ShowUserRequest;
use App\Http\Requests\User\DestroyUserRequest;
use App\Models\Setting;
use Illuminate\Support\Str;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;
class UserController extends ItemController
{
protected const MODEL = User::class;
/**
* @throws Exception
* @api {get, post} /users/list List
* @apiDescription Get list of Users with any params
*
* @apiVersion 4.0.0
* @apiName GetUserList
* @apiGroup User
*
* @apiUse AuthHeader
*
* @apiPermission users_list
* @apiPermission users_full_access
*
* @apiSuccess {Object[]} users List of users.
* @apiSuccess {Integer} users.id The unique ID of the user.
* @apiSuccess {String} users.full_name Full name of the user.
* @apiSuccess {String} users.email Email address of the user.
* @apiSuccess {String} users.url URL associated with the user.
* @apiSuccess {Integer} users.company_id ID of the company the user belongs to.
* @apiSuccess {String} users.avatar URL of the user's avatar image.
* @apiSuccess {Integer} users.screenshots_state The current state of screenshot monitoring.
* @apiSuccess {Boolean} users.manual_time Indicates if manual time tracking is allowed.
* @apiSuccess {Integer} users.computer_time_popup Time in seconds before showing a time popup.
* @apiSuccess {Boolean} users.blur_screenshots Indicates if screenshots are blurred.
* @apiSuccess {Boolean} users.web_and_app_monitoring Indicates if web and app monitoring is enabled.
* @apiSuccess {Integer} users.screenshots_interval Interval in minutes for taking screenshots.
* @apiSuccess {Boolean} users.active Indicates if the user is active.
* @apiSuccess {String} users.deleted_at Deletion timestamp, or `null` if the user is not deleted.
* @apiSuccess {String} users.created_at Creation timestamp of the user.
* @apiSuccess {String} users.updated_at Last update timestamp of the user.
* @apiSuccess {String} users.timezone The timezone of the user, or `null`.
* @apiSuccess {Boolean} users.important Indicates if the user is marked as important.
* @apiSuccess {Boolean} users.change_password Indicates if the user must change their password.
* @apiSuccess {Integer} users.role_id ID of the user's role.
* @apiSuccess {String} users.user_language Language preference of the user.
* @apiSuccess {String} users.type The user type, e.g., "employee".
* @apiSuccess {Boolean} users.invitation_sent Indicates if an invitation has been sent.
* @apiSuccess {Integer} users.nonce Nonce value for secure actions.
* @apiSuccess {Boolean} users.client_installed Indicates if the client software is installed.
* @apiSuccess {Boolean} users.permanent_screenshots Indicates if permanent screenshots are enabled.
* @apiSuccess {String} users.last_activity The last recorded activity timestamp.
* @apiSuccess {Boolean} users.screenshots_state_locked Indicates if screenshot state is locked.
* @apiSuccess {Boolean} users.online Indicates if the user is currently online.
* @apiSuccess {Boolean} users.can_view_team_tab Indicates if the user can view the team tab.
* @apiSuccess {Boolean} users.can_create_task Indicates if the user can create tasks.
*
* @apiSuccessExample {json} Response Example
* HTTP/1.1 200 OK
* {
* [
* {
* "id": 1,
* "full_name": "Admin",
* "email": "admin@cattr.app",
* "url": "",
* "company_id": 1,
* "avatar": "",
* "screenshots_state": 1,
* "manual_time": 0,
* "computer_time_popup": 300,
* "blur_screenshots": false,
* "web_and_app_monitoring": true,
* "screenshots_interval": 5,
* "active": 1,
* "deleted_at": null,
* "created_at": "2023-10-26T10:26:17.000000Z",
* "updated_at": "2024-08-19T10:42:18.000000Z",
* "timezone": null,
* "important": 0,
* "change_password": 0,
* "role_id": 0,
* "user_language": "en",
* "type": "employee",
* "invitation_sent": false,
* "nonce": 0,
* "client_installed": 0,
* "permanent_screenshots": 0,
* "last_activity": "2024-08-19 10:42:18",
* "screenshots_state_locked": false,
* "online": false,
* "can_view_team_tab": true,
* "can_create_task": true
* },
* {
* "id": 2,
* "full_name": "Fabiola Mertz",
* "email": "projectManager@example.com",
* "url": "",
* "company_id": 1,
* "avatar": "",
* "screenshots_state": 2,
* "manual_time": 0,
* "computer_time_popup": 300,
* "blur_screenshots": false,
* "web_and_app_monitoring": true,
* "screenshots_interval": 5,
* "active": 1,
* "deleted_at": null,
* "created_at": "2023-10-26T10:26:17.000000Z",
* "updated_at": "2023-10-26T10:26:17.000000Z",
* "timezone": null,
* "important": 0,
* "change_password": 0,
* "role_id": 2,
* "user_language": "en",
* "type": "employee",
* "invitation_sent": false,
* "nonce": 0,
* "client_installed": 0,
* "permanent_screenshots": 0,
* "last_activity": "2023-10-26 09:44:17",
* "screenshots_state_locked": false,
* "online": false,
* "can_view_team_tab": false,
* "can_create_task": false
* },...
* ]
* }
* @apiUse 400Error
* @apiUse UnauthorizedError
* @apiUse ForbiddenError
*/
public function index(ListUsersRequest $request): JsonResponse
{
return $this->_index($request);
}
/**
* @api {post} /users/create Create
* @apiDescription Create User Entity
*
* @apiVersion 4.0.0
* @apiName CreateUser
* @apiGroup User
*
* @apiUse AuthHeader
*
* @apiPermission users_create
* @apiPermission users_full_access
*
* @apiParam {String} user_language The language of the new user (e.g., "en")
* @apiParam {String} timezone The timezone of the new user (e.g., "Europe/Moscow")
* @apiParam {Integer} role_id ID of the role of the new user
* @apiParam {Integer} active Will new user be active or not `(1 - active, 0 - not)`
* @apiParam {Integer} screenshots_state State of screenshots monitoring (e.g., 1 for enabled)
* @apiParam {Boolean} send_invite Whether to send an invitation to the new user (true - send, false - do not send)
* @apiParam {Boolean} manual_time Whether manual time tracking is enabled for the new user
* @apiParam {Integer} screenshots_interval Interval in minutes for taking screenshots
* @apiParam {Integer} computer_time_popup Time in minutes before showing a time popup
* @apiParam {String} type The type of user (e.g., "employee")
* @apiParam {Boolean} web_and_app_monitoring Whether web and app monitoring is enabled
* @apiParam {String} email New user email
* @apiParam {String} password New user password
* @apiParam {String} full_name New user name
* @apiParamExample {json} Request Example
* {
* "user_language" : "en",
* "timezone" : "Europe/Moscow",
* "role_id" : 2,
* "active" : true,
* "screenshots_state" : 1,
* "send_invite" : 1,
* "manual_time" : 1,
* "screenshots_interval" : 10,
* "computer_time_popup" : 3,
* "type" : "employee",
* "web_and_app_monitoring" : 1,
* "email" : "123@cattr.app",
* "password" : "password",
* "full_name" : "name"
* }
* @apiSuccess {String} full_name Full name of the user.
* @apiSuccess {String} email Email address of the user.
* @apiSuccess {String} user_language Language of the user.
* @apiSuccess {Boolean} active Whether the user is active.
* @apiSuccess {Integer} screenshots_state State of screenshots monitoring.
* @apiSuccess {Boolean} manual_time Whether manual time tracking is enabled.
* @apiSuccess {Integer} screenshots_interval Interval in minutes for taking screenshots.
* @apiSuccess {Integer} computer_time_popup Time in minutes before showing a time popup.
* @apiSuccess {String} timezone Timezone of the user.
* @apiSuccess {Integer} role_id ID of the role assigned to the user.
* @apiSuccess {String} type Type of the user (e.g., "employee").
* @apiSuccess {Boolean} web_and_app_monitoring Whether web and app monitoring is enabled.
* @apiSuccess {Boolean} screenshots_state_locked Whether the screenshot state is locked.
* @apiSuccess {Boolean} invitation_sent Whether an invitation has been sent.
* @apiSuccess {String} updated_at Timestamp of the last update.
* @apiSuccess {String} created_at Timestamp of when the user was created.
* @apiSuccess {Integer} id ID of the created user.
* @apiSuccess {Boolean} online Whether the user is currently online.
* @apiSuccess {Boolean} can_view_team_tab Whether the user can view the team tab.
* @apiSuccess {Boolean} can_create_task Whether the user can create tasks.
*
*
* @apiSuccessExample {json} Response Example
* HTTP/1.1 200 OK
* {
* "full_name": "name",
* "email": "123@cattr.app",
* "user_language": "en",
* "active": 1,
* "screenshots_state": 1,
* "manual_time": 1,
* "screenshots_interval": 10,
* "computer_time_popup": 3,
* "timezone": "Europe/Moscow",
* "role_id": 2,
* "type": "employee",
* "web_and_app_monitoring": true,
* "screenshots_state_locked": true,
* "invitation_sent": true,
* "updated_at": "2024-08-21T14:29:06.000000Z",
* "created_at": "2024-08-21T14:29:06.000000Z",
* "id": 10,
* "online": false,
* "can_view_team_tab": false,
* "can_create_task": false
* }
*
* @apiUse 400Error
* @apiUse ValidationError
* @apiUse UnauthorizedError
* @apiUse ForbiddenError
*/
/**
* @param CreateUserRequest $request
* @return JsonResponse
* @throws Throwable
*/
public function create(CreateUserRequest $request): JsonResponse
{
Filter::listen(Filter::getRequestFilterName(), static function ($requestData) use ($request) {
$requestData['screenshots_state_locked'] = $request->user()->isAdmin() && ScreenshotsState::tryFrom($requestData['screenshots_state'])->mustBeInherited();
return $requestData;
});
return $this->_create($request);
}
/**
* @api {post} /users/edit Edit
* @apiDescription Edit User
*
* @apiVersion 4.0.0
* @apiName EditUser
* @apiGroup User
*
* @apiUse AuthHeader
*
* @apiPermission users_edit
* @apiPermission users_full_access
* @apiParam {String} user_language The language of the new user (e.g., "en")
* @apiParam {String} timezone The timezone of the new user (e.g., "Europe/Moscow")
* @apiParam {Integer} role_id ID of the role of the new user
* @apiParam {Integer} id The ID of the user being edited.
* @apiParam {String} full_name New user name
* @apiParam {String} email New user email
* @apiParam {String} url URL associated with the user
* @apiParam {Integer} company_id The ID of the company to which the user belongs
* @apiParam {String} avatar The URL of the users avatar
* @apiParam {Integer} screenshots_state State of screenshots monitoring (e.g., 1 for enabled)
* @apiParam {Boolean} manual_time Whether manual time tracking is enabled for the new user
* @apiParam {Integer} computer_time_popup Time in minutes before showing a time popup
* @apiParam {Boolean} blur_screenshots Indicates if screenshots are blurred
* @apiParam {Boolean} web_and_app_monitoring Whether web and app monitoring is enabled
* @apiParam {Integer} screenshots_interval Interval in minutes for taking screenshots
* @apiParam {Integer} active Will new user be active or not `(1 - active, 0 - not)`
* @apiParam {String} deleted_at Deletion timestamp, or `null` if the user is not deleted.
* @apiParam {Boolean} send_invite Whether to send an invitation to the new user (true - send, false - do not send)
*
*
*
* @apiParam {String} type The type of user (e.g., "employee")
*
* @apiParam {String} password New user password
*
*
* @apiParamExample {json} Request Example
* {
* "user_language" : "en",
* "timezone" : "Europe/Moscow",
* "role_id" : 2,
* "id" : 3,
* "full_name" : "Rachael Reichert",
* "email": "projectAuditor@example.com",
* "url" : null,
* "company_id" : 1,
* "avatar" : null,
* "screenshots_state" : 1,
* "manual_time" : 0,
* "computer_time_popup" : 300,
* "blur_screenshots" : false,
* "web_and_app_monitoring" : true,
* "screenshots_interval" : 5,
* "active" : true,
* "deleted_at" : null,
* "created_at" : "2023-10-26T10:26:42.000000Z",
* "updated_at" : "2023-10-26T10:26:42.000000Z",
* "important" : 0,
* "change_password" : 0,
* "type" : "employee",
* "invitation_sent" : false,
* "nonce" : 0,
* "client_installed" : 0,
* "permanent_screenshots" : 0,
* "last_activity" : "2023-10-26 10:05:42",
* "screenshots_state_locked" : false,
* "online" : false,
* "can_view_team_tab" : false,
* "can_create_task" : false
* }
* @apiUse UserObject
* @apiUse 400Error
* @apiUse ValidationError
* @apiUse UnauthorizedError
* @apiUse ItemNotFoundError
*/
/**
* @param EditUserRequest $request
* @return JsonResponse
* @throws Throwable
*/
public function edit(EditUserRequest $request): JsonResponse
{
Filter::listen(Filter::getActionFilterName(), static function (User $user) use ($request) {
if ($user->screenshots_state_locked && !$request->user()->isAdmin()) {
$user->screenshots_state = $user->getOriginal('screenshots_state');
return $user;
}
$user->screenshots_state_locked = $request->user()->isAdmin() && ScreenshotsState::tryFrom($user->screenshots_state)->mustBeInherited();
return $user;
});
return $this->_edit($request);
}
/**
* @api {get, post} /users/show Show User
* @apiDescription Retrieves detailed information about a specific user.
*
* @apiVersion 4.0.0
* @apiName ShowUser
* @apiGroup User
*
* @apiUse AuthHeader
*
* @apiPermission users_show
* @apiPermission users_full_access
*
* @apiParam {Integer} id User id
*
* @apiParamExample {json} Request Example:
* {
* "id": 1
* }
* @apiUse UserObject
*
* @apiUse 400Error
* @apiUse UnauthorizedError
* @apiUse ItemNotFoundError
* @apiUse ForbiddenError
* @apiUse ValidationError
*/
/**
* @param ShowUserRequest $request
* @return JsonResponse
* @throws Exception
* @throws Throwable
*/
public function show(ShowUserRequest $request): JsonResponse
{
return $this->_show($request);
}
/**
* @throws Throwable
* @api {post} /users/remove Destroy
* @apiDescription Destroy User
*
* @apiVersion 4.0.0
* @apiName DestroyUser
* @apiGroup User
*
* @apiUse AuthHeader
*
* @apiPermission users_remove
* @apiPermission users_full_access
*
* @apiParam {Integer} id ID of the target user
*
* @apiParamExample {json} Request Example
* {
* "id": 1
* }
*
* @apiSuccess {String} message Destroy status
*
* @apiSuccessExample {json} Response Example
* HTTP/1.1 204 No Content
* {
* }
*
* @apiUse 400Error
* @apiUse ValidationError
* @apiUse ForbiddenError
* @apiUse UnauthorizedError
*/
public function destroy(DestroyUserRequest $request): JsonResponse
{
return $this->_destroy($request);
}
/**
* @throws Exception
* @api {get,post} /users/count Count
* @apiDescription Count Users
*
* @apiVersion 4.0.0
* @apiName Count
* @apiGroup User
*
* @apiUse AuthHeader
*
* @apiPermission users_count
* @apiPermission users_full_access
*
* @apiSuccess {String} total Amount of users that we have
*
* @apiSuccessExample {json} Response Example
* HTTP/1.1 200 OK
* {
* "total": 2
* }
*
* @apiUse 400Error
* @apiUse ForbiddenError
* @apiUse UnauthorizedError
*/
public function count(ListUsersRequest $request): JsonResponse
{
return $this->_count($request);
}
/**
* @param SendInviteUserRequest $request
* @return JsonResponse
* @throws Throwable
*/
/**
* @api {post} /api/users/send-invite Send User Invitation
* @apiDescription Sends an invitation to a user by generating a password, marking the invitation as sent, and dispatching relevant events.
*
* @apiVersion 4.0.0
* @apiName SendUserInvite
* @apiGroup User
*
* @apiUse AuthHeader
*
* @apiPermission users_invite
*
* @apiParam {Integer} id The ID of the user to whom the invitation will be sent.
*
* @apiParamExample {json} Request Example:
* {
* "id": 1
* }
*
* @apiSuccess {String} message A confirmation that the invite was sent successfully.
*
* @apiSuccessExample {json} Success Response:
* HTTP/1.1 204 No Content
*
* @apiUse 400Error
* @apiUse ForbiddenError
* @apiUse UnauthorizedError
*/
public function sendInvite(SendInviteUserRequest $request): JsonResponse
{
$requestId = Filter::process(Filter::getRequestFilterName(), $request->validated('id'));
$itemsQuery = $this->getQuery(['id' => $requestId]);
CatEvent::dispatch(Filter::getBeforeActionEventName(), $requestId);
$item = Filter::process(Filter::getActionFilterName(), $itemsQuery->first());
$password = Str::random();
$item->password = $password;
$item->invitation_sent = true;
$item->save();
throw_unless($item, new NotFoundHttpException);
CatEvent::dispatch(Filter::getAfterActionEventName(), [$requestId, $item]);
$language = Settings::scope('core')->get('language', 'en');
Mail::to($item->email)->locale($language)->send(new UserCreated($item->email, $password));
return responder()->success()->respond(204);
}
/**
* @api {patch} /users/activity Activity
* @apiDescription Updates the time of the user's last activity
*
* @apiVersion 4.0.0
* @apiName Activity
* @apiGroup User
*
* @apiUse AuthHeader
*
* @apiSuccessExample {json} Response Example
* HTTP/1.1 204 No Content
* {
* }
*
* @apiUse UnauthorizedError
*/
public function updateActivity(): JsonResponse
{
$user = request()->user();
CatEvent::dispatch(Filter::getBeforeActionEventName(), $user);
Filter::process(Filter::getActionFilterName(), $user)->update(['last_activity' => Carbon::now()]);
CatEvent::dispatch(Filter::getAfterActionEventName(), $user);
return responder()->success()->respond(204);
}
}