diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2d2c451..ccf4c3d 100755 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,10 +4,10 @@ on: workflow_dispatch: pull_request: branches: - - v4 + - main push: branches: - - v4 + - main jobs: test: @@ -32,7 +32,7 @@ jobs: coverage: none - name: Clone CyanFox-Base - run: git clone --branch v4 https://github.com/CyanFox/Base CyanFox-Base + run: git clone https://github.com/CyanFox/Base CyanFox-Base - name: Setup problem matchers run: | diff --git a/Admin/app/Http/Controllers/AdminActivityController.php b/Admin/app/Http/Controllers/AdminActivityController.php index adb2440..e11a358 100644 --- a/Admin/app/Http/Controllers/AdminActivityController.php +++ b/Admin/app/Http/Controllers/AdminActivityController.php @@ -2,27 +2,28 @@ namespace Modules\Admin\Http\Controllers; +use Dedoc\Scramble\Attributes\Group; use Dedoc\Scramble\Attributes\QueryParameter; use Illuminate\Http\Request; use Spatie\Activitylog\Models\Activity; +#[Group('Admin Activity')] class AdminActivityController { #[QueryParameter('per_page', description: 'Number of activity entries per page', type: 'integer', default: 20, example: 10)] public function getActivity(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.activity') || ! $request->attributes->get('api_key')->can('admin.activity')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.activity')) { + return $apiKey->sendNoPermissionResponse(); } $activityLog = Activity::orderBy('created_at', 'desc') ->paginate($request->query('per_page', 20)); - return response()->json([ - 'message' => 'Activity retrieved successfully', - 'activity_log' => $activityLog->map(function (Activity $activity) { + return apiResponse('Activity retrieved successfully', + $activityLog->map(function (Activity $activity) { $properties = json_decode($activity->properties, true) ?? []; return [ @@ -34,7 +35,6 @@ public function getActivity(Request $request) 'old_values' => $properties['old'] ?? [], 'new_values' => $properties['attributes'] ?? [], ]; - }), - ]); + })); } } diff --git a/Admin/app/Http/Controllers/AdminGroupsController.php b/Admin/app/Http/Controllers/AdminGroupsController.php index be8c01a..6055e83 100644 --- a/Admin/app/Http/Controllers/AdminGroupsController.php +++ b/Admin/app/Http/Controllers/AdminGroupsController.php @@ -17,45 +17,41 @@ class AdminGroupsController #[QueryParameter('per_page', description: 'Number of groups per page', type: 'integer', default: 20, example: 10)] public function getGroups(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.groups') || ! $request->attributes->get('api_key')->can('admin.groups')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.groups')) { + return $apiKey->sendNoPermissionResponse(); } - return response()->json([ - 'message' => 'Groups retrieved successfully', - 'groups' => Role::orderBy('created_at')->paginate($request->query('per_page', 20)), - ]); + return apiResponse('Groups retrieved successfully', + Role::orderBy('created_at')->paginate($request->query('per_page', 20))); } #[PathParameter('groupId', description: 'ID of the group to retrieve', type: 'integer', example: 1)] public function getGroup(Request $request, $groupId) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.groups') || ! $request->attributes->get('api_key')->can('admin.groups')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.groups')) { + return $apiKey->sendNoPermissionResponse(); } $group = Role::find($groupId); if (! $group) { - return response()->json(['error' => 'Group not found'], 404); + return apiResponse('Group not found', null, false, 404); } - return response()->json([ - 'message' => 'Group retrieved successfully', - 'group' => $group->load(['permissions']), - ]); + return apiResponse('Group retrieved successfully', + $group->load(['permissions'])); } public function createGroup(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.groups.create') || ! $request->attributes->get('api_key')->can('admin.groups.create')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.groups.create')) { + return $apiKey->sendNoPermissionResponse(); } $request->validate([ @@ -66,25 +62,23 @@ public function createGroup(Request $request) $group = CreateGroupAction::run($request->only(['name', 'guard_name'])); $group->syncPermissions($request->input('permissions', [])); - return response()->json([ - 'message' => 'Group created successfully', - 'group' => $group->load(['permissions']), - ]); + return apiResponse('Group created successfully', + $group->load(['permissions'])); } #[PathParameter('groupId', description: 'ID of the group to update', type: 'integer', example: 1)] public function updateGroup(Request $request, $groupId) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.groups.update') || ! $request->attributes->get('api_key')->can('admin.groups.update')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.groups.update')) { + return $apiKey->sendNoPermissionResponse(); } $group = Role::find($groupId); if (! $group) { - return response()->json(['error' => 'Group not found'], 404); + return apiResponse('Group not found', null, false, 404); } $request->validate([ @@ -95,31 +89,27 @@ public function updateGroup(Request $request, $groupId) UpdateGroupAction::run($group, $request->only(['name', 'guard_name'])); $group->syncPermissions($request->input('permissions', [])); - return response()->json([ - 'message' => 'Group updated successfully', - 'group' => $group->fresh()->load(['permissions']), - ]); + return apiResponse('Group updated successfully', + $group->fresh()->load(['permissions'])); } #[PathParameter('groupId', description: 'ID of the group to delete', type: 'integer', example: 1)] public function deleteGroup(Request $request, $groupId) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.groups.delete') || ! $request->attributes->get('api_key')->can('admin.groups.delete')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.groups.delete')) { + return $apiKey->sendNoPermissionResponse(); } $group = Role::find($groupId); if (! $group) { - return response()->json(['error' => 'Group not found'], 404); + return apiResponse('Group not found', null, false, 404); } DeleteGroupAction::run($group); - return response()->json([ - 'message' => 'Group deleted successfully', - ]); + return apiResponse('Group deleted successfully'); } } diff --git a/Admin/app/Http/Controllers/AdminModuleController.php b/Admin/app/Http/Controllers/AdminModuleController.php index ba8ce8c..dbd77cc 100644 --- a/Admin/app/Http/Controllers/AdminModuleController.php +++ b/Admin/app/Http/Controllers/AdminModuleController.php @@ -15,10 +15,10 @@ class AdminModuleController #[QueryParameter('show_disabled', description: 'Include disabled modules', type: 'boolean', default: true, example: false)] public function getModules(Request $request) { - $user = request()->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.modules') || ! $request->attributes->get('api_key')->can('admin.modules')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.modules')) { + return $apiKey->sendNoPermissionResponse(); } $showDisabled = $request->query('show_disabled', true); @@ -29,173 +29,159 @@ public function getModules(Request $request) $modules = Module::allEnabled(); } - return response()->json([ - 'message' => 'Modules retrieved successfully', - 'modules' => collect($modules)->map(function ($module) { + return apiResponse('Modules retrieved successfully', + collect($modules)->map(function ($module) { return [ 'name' => $module->getName(), 'enabled' => $module->isEnabled(), 'version' => ModuleManager::getVersion($module->getName()), 'remote_version' => ModuleManager::getRemoteVersion($module->getName()), ]; - })->values()->toArray(), - ]); + })->values()->toArray()); } - #[PathParameter('moduleName', description: 'Name of the module to retrieve', type: 'string', example: 'Admin')] - public function getModule(Request $request, $moduleName) + #[PathParameter('moduleName', description: 'Name of the module to enable', type: 'string', example: 'Admin')] + public function enableModule(Request $request, $moduleName) { - $user = request()->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.modules') || ! $request->attributes->get('api_key')->can('admin.modules')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.modules.enable')) { + return $apiKey->sendNoPermissionResponse(); } $module = Module::find($moduleName); - if (! $module) { + if (!$module) { return response()->json(['error' => 'Module not found'], 404); } + ModuleManager::getModule($moduleName)->enable(); + return response()->json([ - 'message' => 'Module retrieved successfully', - 'module' => [ - 'name' => $module->getName(), - 'enabled' => $module->isEnabled(), - 'version' => ModuleManager::getVersion($module->getName()), - 'remote_version' => ModuleManager::getRemoteVersion($module->getName()), - ], + 'message' => 'Module enabled successfully', + 'module' => $module->getName(), ]); } - #[PathParameter('moduleName', description: 'Name of the module to enable', type: 'string', example: 'Admin')] - public function enableModule(Request $request, $moduleName) + #[PathParameter('moduleName', description: 'Name of the module to retrieve', type: 'string', example: 'Admin')] + public function getModule(Request $request, $moduleName) { - $user = request()->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.modules.enable') || ! $request->attributes->get('api_key')->can('admin.modules.enable')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.modules')) { + return $apiKey->sendNoPermissionResponse(); } $module = Module::find($moduleName); - if (! $module) { - return response()->json(['error' => 'Module not found'], 404); + if (!$module) { + return apiResponse('Module not found', null, false, 404); } - ModuleManager::getModule($moduleName)->enable(); - - return response()->json([ - 'message' => 'Module enabled successfully', - 'module' => $module->getName(), + return apiResponse('Module retrieved successfully', [ + 'name' => $module->getName(), + 'enabled' => $module->isEnabled(), + 'version' => ModuleManager::getVersion($module->getName()), + 'remote_version' => ModuleManager::getRemoteVersion($module->getName()), ]); } #[PathParameter('moduleName', description: 'Name of the module to disable', type: 'string', example: 'Admin')] public function disableModule(Request $request, $moduleName) { - $user = request()->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.modules.disable') || ! $request->attributes->get('api_key')->can('admin.modules.disable')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.modules.disable')) { + return $apiKey->sendNoPermissionResponse(); } $module = Module::find($moduleName); - if (! $module) { - return response()->json(['error' => 'Module not found'], 404); + if (!$module) { + return apiResponse('Module not found', null, false, 404); } ModuleManager::getModule($moduleName)->disable(); - return response()->json([ - 'message' => 'Module disabled successfully', - 'module' => $module->getName(), - ]); + return apiResponse('Module disabled successfully', + $module->getName()); } #[PathParameter('moduleName', description: 'Name of the module to delete', type: 'string', example: 'Admin')] public function deleteModule(Request $request, $moduleName) { - $user = request()->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.modules.delete') || ! $request->attributes->get('api_key')->can('admin.modules.delete')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.modules.delete')) { + return $apiKey->sendNoPermissionResponse(); } $module = Module::find($moduleName); - if (! $module) { - return response()->json(['error' => 'Module not found'], 404); + if (!$module) { + return apiResponse('Module not found', null, false, 404); } ModuleManager::getModule($moduleName)->delete(); - return response()->json([ - 'message' => 'Module deleted successfully', - 'module' => $module->getName(), - ]); + return apiResponse('Module deleted successfully', + $module->getName()); } #[PathParameter('moduleName', description: 'Name of the module to retrieve', type: 'string', example: 'Admin')] public function getModuleVersion(Request $request, $moduleName) { - $user = request()->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.modules') || ! $request->attributes->get('api_key')->can('admin.modules')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.modules')) { + return $apiKey->sendNoPermissionResponse(); } $module = Module::find($moduleName); - if (! $module) { - return response()->json(['error' => 'Module not found'], 404); + if (!$module) { + return apiResponse('Module not found', null, false, 404); } - return response()->json([ - 'message' => 'Module version retrieved successfully', - 'version' => ModuleManager::getVersion($moduleName), - ]); + return apiResponse('Module version retrieved successfully', + ModuleManager::getVersion($moduleName)); } #[PathParameter('moduleName', description: 'Name of the module to retrieve', type: 'string', example: 'Admin')] public function getRemoteModuleVersion(Request $request, $moduleName) { - $user = request()->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.modules') || ! $request->attributes->get('api_key')->can('admin.modules')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.modules')) { + return $apiKey->sendNoPermissionResponse(); } $module = Module::find($moduleName); - if (! $module) { - return response()->json(['error' => 'Module not found'], 404); + if (!$module) { + return apiResponse('Module not found', null, false, 404); } - return response()->json([ - 'message' => 'Remote module version retrieved successfully', - 'version' => ModuleManager::getRemoteVersion($moduleName), - ]); + return apiResponse('Remote module version retrieved successfully', + ModuleManager::getRemoteVersion($moduleName)); } #[PathParameter('moduleName', description: 'Name of the module to retrieve', type: 'string', example: 'Admin')] public function isModuleUpToDate(Request $request, $moduleName) { - $user = request()->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.modules') || ! $request->attributes->get('api_key')->can('admin.modules')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.modules')) { + return $apiKey->sendNoPermissionResponse(); } $module = Module::find($moduleName); - if (! $module) { - return response()->json(['error' => 'Module not found'], 404); + if (!$module) { + return apiResponse('Module not found', null, false, 404); } - return response()->json([ - 'message' => 'Module version status retrieved successfully', + return apiResponse('Module version status retrieved successfully', [ 'up_to_date' => ModuleManager::getVersion($moduleName) === ModuleManager::getRemoteVersion($moduleName), 'current_version' => ModuleManager::getVersion($moduleName), 'remote_version' => ModuleManager::getRemoteVersion($moduleName), diff --git a/Admin/app/Http/Controllers/AdminPermissionsController.php b/Admin/app/Http/Controllers/AdminPermissionsController.php index 6e44bd3..b4c2eaa 100644 --- a/Admin/app/Http/Controllers/AdminPermissionsController.php +++ b/Admin/app/Http/Controllers/AdminPermissionsController.php @@ -17,35 +17,33 @@ class AdminPermissionsController #[QueryParameter('per_page', description: 'Number of permissions per page', type: 'integer', default: 20, example: 10)] public function getPermissions(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.permissions') || ! $request->attributes->get('api_key')->can('admin.permissions')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.permissions')) { + return $apiKey->sendNoPermissionResponse(); } - return response()->json([ - 'message' => 'Permissions retrieved successfully', - 'permissions' => Permission::orderBy('created_at') - ->paginate($request->query('per_page', 20)), - ]); + return apiResponse('Permissions retrieved successfully', + Permission::orderBy('created_at') + ->paginate($request->query('per_page', 20))); } #[PathParameter('permissionId', description: 'ID of the permission to retrieve', type: 'integer', example: 1)] public function getPermission(Request $request, $permissionId) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.permissions') || ! $request->attributes->get('api_key')->can('admin.permissions')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.permissions')) { + return $apiKey->sendNoPermissionResponse(); } $permission = Permission::find($permissionId); - if (! $permission) { - return response()->json(['error' => 'Permission not found'], 404); + if (!$permission) { + return apiResponse('Permission not found', null, false, 404); } - return response()->json([ + return apiResponse([ 'message' => 'Permission retrieved successfully', 'permission' => $permission, ]); @@ -53,10 +51,10 @@ public function getPermission(Request $request, $permissionId) public function createPermission(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.permissions.create') || ! $request->attributes->get('api_key')->can('admin.permissions.create')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.permissions.create')) { + return $apiKey->sendNoPermissionResponse(); } $request->validate([ @@ -66,59 +64,51 @@ public function createPermission(Request $request) $permission = CreatePermissionAction::run($request->only(['name', 'guard_name'])); - return response()->json([ - 'message' => 'Permission created successfully', - 'permission' => $permission, - ]); + return apiResponse('Permission created successfully', $permission); } #[PathParameter('permissionId', description: 'ID of the permission to update', type: 'integer', example: 1)] public function updatePermission(Request $request, $permissionId) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.permissions.update') || ! $request->attributes->get('api_key')->can('admin.permissions.update')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.permissions.update')) { + return $apiKey->sendNoPermissionResponse(); } $permission = Permission::find($permissionId); - if (! $permission) { - return response()->json(['error' => 'Permission not found'], 404); + if (!$permission) { + return apiResponse('Permission not found', null, false, 404); } $request->validate([ - 'name' => 'required|string|unique:permissions,name,'.$permissionId, + 'name' => 'required|string|unique:permissions,name,' . $permissionId, 'guard_name' => 'required|string', ]); UpdatePermissionAction::run($permission, $request->only(['name', 'guard_name'])); - return response()->json([ - 'message' => 'Permission updated successfully', - 'permission' => $permission->fresh(), - ]); + return apiResponse('Permission updated successfully', $permission->fresh()); } #[PathParameter('permissionId', description: 'ID of the permission to delete', type: 'integer', example: 1)] public function deletePermission(Request $request, $permissionId) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.permissions.delete') || ! $request->attributes->get('api_key')->can('admin.permissions.delete')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.permissions.delete')) { + return $apiKey->sendNoPermissionResponse(); } $permission = Permission::find($permissionId); - if (! $permission) { - return response()->json(['error' => 'Permission not found'], 404); + if (!$permission) { + return apiResponse('Permission not found', null, false, 404); } DeletePermissionAction::run($permission); - return response()->json([ - 'message' => 'Permission deleted successfully', - ]); + return apiResponse('Permission deleted successfully'); } } diff --git a/Admin/app/Http/Controllers/AdminSettingsController.php b/Admin/app/Http/Controllers/AdminSettingsController.php index 42dcd20..a05afa8 100644 --- a/Admin/app/Http/Controllers/AdminSettingsController.php +++ b/Admin/app/Http/Controllers/AdminSettingsController.php @@ -15,37 +15,33 @@ class AdminSettingsController { public function getSettings(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.settings.editor') || ! $request->attributes->get('api_key')->can('admin.settings.editor')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.settings.editor')) { + return $apiKey->sendNoPermissionResponse(); } - return response()->json([ - 'message' => 'Settings retrieved successfully', - 'settings' => Setting::all(), - ]); + return apiResponse('Settings retrieved successfully', Setting::all()); } #[QueryParameter('encrypted', description: 'Whether to return decrypted settings', type: 'boolean', default: false, example: true)] #[PathParameter('settingsKey', description: 'Key of the setting to retrieve', type: 'string', example: 'internal.app.name')] public function getSetting(Request $request, $settingsKey) { - $user = $request->attributes->get('api_key')->user; $isEncrypted = $request->query('encrypted', false); + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.settings.editor') || ! $request->attributes->get('api_key')->can('admin.settings.editor')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.settings.editor')) { + return $apiKey->sendNoPermissionResponse(); } $setting = SettingsManager::getSetting($settingsKey, isEncrypted: $isEncrypted); if (! $setting) { - return response()->json(['error' => 'Setting not found'], 404); + return apiResponse('Setting not found', null, false, 404); } - return response()->json([ - 'message' => 'Setting retrieved successfully', + return apiResponse('Setting retrieved successfully', [ 'key' => $settingsKey, 'value' => $setting, ]); @@ -54,10 +50,10 @@ public function getSetting(Request $request, $settingsKey) #[PathParameter('settingsKey', description: 'Key of the setting to update', type: 'string', example: 'internal.app.name')] public function updateSetting(Request $request, $settingsKey) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.settings.editor') || ! $request->attributes->get('api_key')->can('admin.settings.editor')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.settings.editor')) { + return $apiKey->sendNoPermissionResponse(); } $value = $request->input('value'); @@ -66,8 +62,7 @@ public function updateSetting(Request $request, $settingsKey) SettingsManager::updateSetting($settingsKey, $value, isLocked: $locked, isEncrypted: $isEncrypted); - return response()->json([ - 'message' => 'Setting updated successfully', + return apiResponse('Setting updated successfully', [ 'key' => $settingsKey, 'value' => $value, ]); @@ -76,26 +71,23 @@ public function updateSetting(Request $request, $settingsKey) #[PathParameter('settingsKey', description: 'Key of the setting to delete', type: 'string', example: 'internal.app.name')] public function deleteSetting(Request $request, $settingsKey) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.settings.editor') || ! $request->attributes->get('api_key')->can('admin.settings.editor')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.settings.editor')) { + return $apiKey->sendNoPermissionResponse(); } SettingsManager::deleteSetting($settingsKey); - return response()->json([ - 'message' => 'Setting deleted successfully', - 'key' => $settingsKey, - ]); + return apiResponse('Setting deleted successfully', $settingsKey); } public function createSetting(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.settings.editor') || ! $request->attributes->get('api_key')->can('admin.settings.editor')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.settings.editor')) { + return $apiKey->sendNoPermissionResponse(); } $request->validate([ @@ -111,55 +103,46 @@ public function createSetting(Request $request) isEncrypted: $request->input('encrypted', false), ); - return response()->json([ - 'message' => 'Setting created successfully', - 'setting' => $setting, - ]); + return apiResponse('Setting created successfully', $setting); } public function encryptValue(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.settings.editor') || ! $request->attributes->get('api_key')->can('admin.settings.editor')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.settings.editor')) { + return $apiKey->sendNoPermissionResponse(); } $value = $request->input('value'); if (blank($value)) { - return response()->json(['error' => 'Value is required'], 400); + return apiResponse('Value is required', null, false, 400); } - return response()->json([ - 'message' => 'Value encrypted successfully', - 'value' => encrypt($value), - ]); + return apiResponse('Value encrypted successfully', encrypt($value)); } public function decryptValue(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.settings.editor') || ! $request->attributes->get('api_key')->can('admin.settings.editor')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.settings.editor')) { + return $apiKey->sendNoPermissionResponse(); } $value = $request->input('value'); if (blank($value)) { - return response()->json(['error' => 'Value is required'], 400); + return apiResponse('Value is required', null, false, 400); } try { $decryptedValue = decrypt($value); } catch (Exception $e) { - return response()->json(['error' => 'Decryption failed: '.$e->getMessage()], 400); + return apiResponse('Decryption failed', $e->getMessage(), false, 500); } - return response()->json([ - 'message' => 'Value decrypted successfully', - 'value' => $decryptedValue, - ]); + return apiResponse('Value decrypted successfully', $decryptedValue); } } diff --git a/Admin/app/Http/Controllers/AdminUsersController.php b/Admin/app/Http/Controllers/AdminUsersController.php index d0e2cad..59b7bef 100644 --- a/Admin/app/Http/Controllers/AdminUsersController.php +++ b/Admin/app/Http/Controllers/AdminUsersController.php @@ -20,45 +20,39 @@ class AdminUsersController #[QueryParameter('per_page', description: 'Number of users per page', type: 'integer', default: 20, example: 10)] public function getUsers(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.users') || ! $request->attributes->get('api_key')->can('admin.users')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.users')) { + return $apiKey->sendNoPermissionResponse(); } - return response()->json([ - 'message' => 'Users retrieved successfully', - 'users' => User::orderBy('created_at')->paginate($request->query('per_page', 20)), - ]); + return apiResponse('Users retrieved successfully', User::orderBy('created_at')->paginate($request->query('per_page', 20))); } #[PathParameter('userId', description: 'ID of the user to retrieve', type: 'integer', example: 1)] public function getUser(Request $request, $userId) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.users') || ! $request->attributes->get('api_key')->can('admin.users')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.users')) { + return $apiKey->sendNoPermissionResponse(); } $user = User::find($userId); - if (! $user) { - return response()->json(['error' => 'User not found'], 404); + if (!$user) { + return apiResponse('User not found', null, false, 404); } - return response()->json([ - 'message' => 'User retrieved successfully', - 'user' => $user->load(['roles', 'permissions']), - ]); + return apiResponse('User retrieved successfully', $user->load(['roles', 'permissions'])); } public function createUser(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.users.create') || ! $request->attributes->get('api_key')->can('admin.users.create')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.users.create')) { + return $apiKey->sendNoPermissionResponse(); } $data = $request->validate([ @@ -84,26 +78,23 @@ public function createUser(Request $request) $permissionIds = Permission::whereIn('name', $request->input('permissions', []))->pluck('id')->toArray(); $user->permissions()->sync($permissionIds); - return response()->json([ - 'message' => 'User created successfully', - 'user' => $user->load(['roles', 'permissions']), - ]); + return apiResponse('User created successfully', $user->load(['roles', 'permissions'])); } #[PathParameter('userId', description: 'ID of the user to update', type: 'integer', example: 1)] public function updateUser(Request $request, $userId) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.users.update') || ! $request->attributes->get('api_key')->can('admin.users.update')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.users.update')) { + return $apiKey->sendNoPermissionResponse(); } $data = $request->validate([ 'first_name' => 'nullable|string', 'last_name' => 'nullable|string', - 'email' => 'nullable|email|unique:users,email,'.$request->route('userId'), - 'username' => 'nullable|string|unique:users,username,'.$request->route('userId'), + 'email' => 'nullable|email|unique:users,email,' . $request->route('userId'), + 'username' => 'nullable|string|unique:users,username,' . $request->route('userId'), 'password' => ['nullable', 'string', new Password], 'theme' => 'nullable|string', 'language' => 'nullable|string|max:255', @@ -116,8 +107,8 @@ public function updateUser(Request $request, $userId) $user = User::find($userId); - if (! $user) { - return response()->json(['error' => 'User not found'], 404); + if (!$user) { + return apiResponse('User not found', null, false, 404); } UpdateUserAction::run($user, $data); @@ -128,31 +119,26 @@ public function updateUser(Request $request, $userId) $permissionIds = Permission::whereIn('name', $request->input('permissions', []))->pluck('id')->toArray(); $user->permissions()->sync($permissionIds); - return response()->json([ - 'message' => 'User updated successfully', - 'user' => $user->fresh()->load(['roles', 'permissions']), - ]); + return apiResponse('User updated successfully', $user->fresh()->load(['roles', 'permissions'])); } #[PathParameter('userId', description: 'ID of the user to delete', type: 'integer', example: 1)] public function deleteUser(Request $request, $userId) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.users.delete') || ! $request->attributes->get('api_key')->can('admin.users.delete')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.users.delete')) { + return $apiKey->sendNoPermissionResponse(); } $user = User::find($userId); - if (! $user) { - return response()->json(['error' => 'User not found'], 404); + if (!$user) { + return apiResponse('User not found', null, false, 404); } DeleteUserAction::run($user); - return response()->json([ - 'message' => 'User deleted successfully', - ]); + return apiResponse('User deleted successfully'); } } diff --git a/Admin/app/Http/Controllers/AdminVersionController.php b/Admin/app/Http/Controllers/AdminVersionController.php index 06fe3d3..1a5276d 100644 --- a/Admin/app/Http/Controllers/AdminVersionController.php +++ b/Admin/app/Http/Controllers/AdminVersionController.php @@ -5,97 +5,103 @@ use App\Facades\ModuleManager; use App\Facades\VersionManager; use Dedoc\Scramble\Attributes\Group; +use Dedoc\Scramble\Attributes\QueryParameter; use Illuminate\Http\Request; #[Group('Admin Version')] class AdminVersionController { - public function getCurrentBaseVersion(Request $request) + public function isBaseUpToDate(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.dashboard') || ! $request->attributes->get('api_key')->can('admin.dashboard')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.dashboard')) { + return $apiKey->sendNoPermissionResponse(); } - return response()->json([ - 'message' => 'Current base version retrieved successfully', - 'version' => VersionManager::getCurrentBaseVersion(), - 'dev' => VersionManager::isDevVersion(), + return apiResponse('Base version status retrieved successfully', [ + 'up_to_date' => VersionManager::isBaseUpToDate(), + 'current_version' => VersionManager::getCurrentBaseVersion(), + 'remote_version' => VersionManager::getRemoteBaseVersion(), ]); } - public function getRemoteBaseVersion(Request $request) + public function getCurrentBaseVersion(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.dashboard') || ! $request->attributes->get('api_key')->can('admin.dashboard')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.dashboard')) { + return $apiKey->sendNoPermissionResponse(); } - return response()->json([ - 'message' => 'Remote base version retrieved successfully', - 'version' => VersionManager::getRemoteBaseVersion(), + return apiResponse('Current base version retrieved successfully', [ + 'version' => VersionManager::getCurrentBaseVersion(), + 'dev' => VersionManager::isDevVersion(), ]); } - public function isBaseUpToDate(Request $request) + public function getRemoteBaseVersion(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.dashboard') || ! $request->attributes->get('api_key')->can('admin.dashboard')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.dashboard')) { + return $apiKey->sendNoPermissionResponse(); } - return response()->json([ - 'message' => 'Base version status retrieved successfully', - 'up_to_date' => VersionManager::isBaseUpToDate(), - 'current_version' => VersionManager::getCurrentBaseVersion(), - 'remote_version' => VersionManager::getRemoteBaseVersion(), - ]); + return apiResponse('Remote base version retrieved successfully', VersionManager::getRemoteBaseVersion()); } + #[QueryParameter('module', 'The name of the module to check the version for', required: true, example: 'Admin')] public function getCurrentModuleVersion(Request $request) { - $user = $request->attributes->get('api_key')->user; + $request->validate([ + 'module' => 'required|string', + ]); + + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.dashboard') || ! $request->attributes->get('api_key')->can('admin.dashboard')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.modules')) { + return $apiKey->sendNoPermissionResponse(); } - return response()->json([ - 'message' => 'Current module version retrieved successfully', - 'version' => ModuleManager::getVersion('Admin'), - ]); + return apiResponse('Current module version retrieved successfully', ModuleManager::getVersion($request->query('module'))); } + #[QueryParameter('module', 'The name of the module to check the version for', required: true, example: 'Admin')] public function getRemoteModuleVersion(Request $request) { - $user = $request->attributes->get('api_key')->user; + $request->validate([ + 'module' => 'required|string', + ]); + + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.dashboard') || ! $request->attributes->get('api_key')->can('admin.dashboard')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.modules')) { + return $apiKey->sendNoPermissionResponse(); } - return response()->json([ - 'message' => 'Remote module version retrieved successfully', - 'version' => ModuleManager::getRemoteVersion('Admin'), - ]); + return apiResponse('Remote module version retrieved successfully', ModuleManager::getRemoteVersion($request->query('module'))); } + #[QueryParameter('module', 'The name of the module to check the version for', required: true, example: 'Admin')] public function isModuleUpToDate(Request $request) { - $user = $request->attributes->get('api_key')->user; + $request->validate([ + 'module' => 'required|string', + ]); + + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.dashboard') || ! $request->attributes->get('api_key')->can('admin.dashboard')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.modules')) { + return $apiKey->sendNoPermissionResponse(); } - return response()->json([ - 'message' => 'Module version status retrieved successfully', - 'version' => ModuleManager::getVersion('Admin') === ModuleManager::getRemoteVersion('Admin'), - 'current_version' => ModuleManager::getVersion('Admin'), - 'remote_version' => ModuleManager::getRemoteVersion('Admin'), + $module = $request->query('module'); + + return apiResponse('Module version status retrieved successfully', [ + 'version' => ModuleManager::getVersion($module) === ModuleManager::getRemoteVersion($module), + 'current_version' => ModuleManager::getVersion($module), + 'remote_version' => ModuleManager::getRemoteVersion($module), ]); } } diff --git a/Admin/module.json b/Admin/module.json index 27cc9b2..7f016db 100755 --- a/Admin/module.json +++ b/Admin/module.json @@ -5,7 +5,7 @@ "keywords": ["admin", "cyanfox", "base"], "authors": ["CyanFox"], "license": "MIT", - "version": "25.08.2", + "version": "2025.10.0", "remote_version_url": "https://raw.githubusercontent.com/CyanFox/Modules/v4/Admin/module.json", "priority": 200, "providers": [ diff --git a/Admin/routes/api.php b/Admin/routes/api.php index 5792f5a..de4c16e 100755 --- a/Admin/routes/api.php +++ b/Admin/routes/api.php @@ -21,67 +21,67 @@ use Modules\Admin\Http\Controllers\AdminVersionController; Route::group(['middleware' => ['api_key'], 'prefix' => 'v1/admin'], function () { - Route::get('activity', [AdminActivityController::class, 'getActivity'])->name('Get Activity'); + Route::get('activity', [AdminActivityController::class, 'getActivity'])->name('admin.activity'); Route::group(['prefix' => 'versions'], function () { Route::group(['prefix' => 'current'], function () { - Route::get('base', [AdminVersionController::class, 'getCurrentBaseVersion'])->name('Get Current Base Version'); - Route::get('module', [AdminVersionController::class, 'getCurrentModuleVersion'])->name('Get Current Module Version'); + Route::get('base', [AdminVersionController::class, 'getCurrentBaseVersion'])->name('admin.versions.base.current'); + Route::get('module', [AdminVersionController::class, 'getCurrentModuleVersion'])->name('admin.versions.module.current'); }); Route::group(['prefix' => 'remote'], function () { - Route::get('base', [AdminVersionController::class, 'getRemoteBaseVersion'])->name('Get Remote Base Version'); - Route::get('module', [AdminVersionController::class, 'getRemoteModuleVersion'])->name('Get Remote Module Version'); + Route::get('base', [AdminVersionController::class, 'getRemoteBaseVersion'])->name('admin.versions.base.remote'); + Route::get('module', [AdminVersionController::class, 'getRemoteModuleVersion'])->name('admin.versions.module.remote'); }); Route::group(['prefix' => 'status'], function () { - Route::get('base', [AdminVersionController::class, 'isBaseUpToDate'])->name('Is Base Up To Date'); - Route::get('module', [AdminVersionController::class, 'isModuleUpToDate'])->name('Is Module Up To Date'); + Route::get('base', [AdminVersionController::class, 'isBaseUpToDate'])->name('admin.versions.base.status'); + Route::get('module', [AdminVersionController::class, 'isModuleUpToDate'])->name('admin.versions.module.status'); }); }); Route::group(['prefix' => 'users'], function () { - Route::get('/', [AdminUsersController::class, 'getUsers'])->name('Get Users'); - Route::post('/', [AdminUsersController::class, 'createUser'])->name('Create User'); - Route::get('{userId}', [AdminUsersController::class, 'getUser'])->name('Get specific User'); - Route::put('{userId}', [AdminUsersController::class, 'updateUser'])->name('Update User'); - Route::delete('{userId}', [AdminUsersController::class, 'deleteUser'])->name('Delete User'); + Route::get('/', [AdminUsersController::class, 'getUsers'])->name('admin.users'); + Route::post('/', [AdminUsersController::class, 'createUser'])->name('admin.users.create'); + Route::get('{userId}', [AdminUsersController::class, 'getUser'])->name('admin.users.view'); + Route::put('{userId}', [AdminUsersController::class, 'updateUser'])->name('admin.users.update'); + Route::delete('{userId}', [AdminUsersController::class, 'deleteUser'])->name('admin.users.delete'); }); Route::group(['prefix' => 'groups'], function () { - Route::get('/', [AdminGroupsController::class, 'getGroups'])->name('Get Groups'); - Route::post('/', [AdminGroupsController::class, 'createGroup'])->name('Create Group'); - Route::get('{groupId}', [AdminGroupsController::class, 'getGroup'])->name('Get specific Group'); - Route::put('{groupId}', [AdminGroupsController::class, 'updateGroup'])->name('Update Group'); - Route::delete('{groupId}', [AdminGroupsController::class, 'deleteGroup'])->name('Delete Group'); + Route::get('/', [AdminGroupsController::class, 'getGroups'])->name('admin.groups'); + Route::post('/', [AdminGroupsController::class, 'createGroup'])->name('admin.groups.create'); + Route::get('{groupId}', [AdminGroupsController::class, 'getGroup'])->name('admin.groups.view'); + Route::put('{groupId}', [AdminGroupsController::class, 'updateGroup'])->name('admin.groups.update'); + Route::delete('{groupId}', [AdminGroupsController::class, 'deleteGroup'])->name('admin.groups.delete'); }); Route::group(['prefix' => 'permissions'], function () { - Route::get('/', [AdminPermissionsController::class, 'getPermissions'])->name('Get Permissions'); - Route::post('/', [AdminPermissionsController::class, 'createPermission'])->name('Create Permission'); - Route::get('{permissionId}', [AdminPermissionsController::class, 'getPermission'])->name('Get specific Permission'); - Route::put('{permissionId}', [AdminPermissionsController::class, 'updatePermission'])->name('Update Permission'); - Route::delete('{permissionId}', [AdminPermissionsController::class, 'deletePermission'])->name('Delete Permission'); + Route::get('/', [AdminPermissionsController::class, 'getPermissions'])->name('admin.permissions'); + Route::post('/', [AdminPermissionsController::class, 'createPermission'])->name('admin.permissions.create'); + Route::get('{permissionId}', [AdminPermissionsController::class, 'getPermission'])->name('admin.permissions.view'); + Route::put('{permissionId}', [AdminPermissionsController::class, 'updatePermission'])->name('admin.permissions.update'); + Route::delete('{permissionId}', [AdminPermissionsController::class, 'deletePermission'])->name('admin.permissions.delete'); }); Route::group(['prefix' => 'settings'], function () { - Route::get('/', [AdminSettingsController::class, 'getSettings'])->name('Get Settings'); - Route::post('/', [AdminSettingsController::class, 'createSetting'])->name('Create Setting'); - Route::post('encrypt', [AdminSettingsController::class, 'encryptValue'])->name('Encrypt Value'); - Route::post('decrypt', [AdminSettingsController::class, 'decryptValue'])->name('Decrypt Value'); - Route::get('{settingKey}', [AdminSettingsController::class, 'getSetting'])->name('Get specific Setting'); - Route::put('{settingKey}', [AdminSettingsController::class, 'updateSetting'])->name('Update Setting'); - Route::delete('{settingKey}', [AdminSettingsController::class, 'deleteSetting'])->name('Delete Setting'); + Route::get('/', [AdminSettingsController::class, 'getSettings'])->name('admin.settings'); + Route::post('/', [AdminSettingsController::class, 'createSetting'])->name('admin.settings.create'); + Route::post('encrypt', [AdminSettingsController::class, 'encryptValue'])->name('admin.settings.encrypt'); + Route::post('decrypt', [AdminSettingsController::class, 'decryptValue'])->name('admin.settings.decrypt'); + Route::get('{settingKey}', [AdminSettingsController::class, 'getSetting'])->name('admin.settings.view'); + Route::put('{settingKey}', [AdminSettingsController::class, 'updateSetting'])->name('admin.settings.update'); + Route::delete('{settingKey}', [AdminSettingsController::class, 'deleteSetting'])->name('admin.settings.delete'); }); Route::group(['prefix' => 'modules'], function () { - Route::get('/', [AdminModuleController::class, 'getModules'])->name('Get Modules'); - Route::get('{moduleName}', [AdminModuleController::class, 'getModule'])->name('Get specific Module'); - Route::patch('{moduleName}/disable', [AdminModuleController::class, 'disableModule'])->name('Disable Module'); - Route::patch('{moduleName}/enable', [AdminModuleController::class, 'enableModule'])->name('Enable Module'); - Route::delete('{moduleName}', [AdminModuleController::class, 'deleteModule'])->name('Delete Module'); + Route::get('/', [AdminModuleController::class, 'getModules'])->name('admin.modules'); + Route::get('{moduleName}', [AdminModuleController::class, 'getModule'])->name('admin.modules.view'); + Route::patch('{moduleName}/disable', [AdminModuleController::class, 'disableModule'])->name('admin.modules.disable'); + Route::patch('{moduleName}/enable', [AdminModuleController::class, 'enableModule'])->name('admin.modules.enable'); + Route::delete('{moduleName}', [AdminModuleController::class, 'deleteModule'])->name('admin.modules.delete'); Route::group(['prefix' => '{moduleName}/version'], function () { - Route::get('current', [AdminModuleController::class, 'getModuleVersion'])->name('Get Current Module Version'); - Route::get('remote', [AdminModuleController::class, 'getRemoteModuleVersion'])->name('Get Remote Module Version'); - Route::get('status', [AdminModuleController::class, 'isModuleUpToDate'])->name('Is Module Up To Date'); + Route::get('current', [AdminModuleController::class, 'getModuleVersion'])->name('admin.modules.version.current'); + Route::get('remote', [AdminModuleController::class, 'getRemoteModuleVersion'])->name('admin.modules.version.remote'); + Route::get('status', [AdminModuleController::class, 'isModuleUpToDate'])->name('admin.modules.version.status'); }); }); }); diff --git a/Announcements/app/Http/Controllers/AnnouncementsController.php b/Announcements/app/Http/Controllers/AnnouncementsController.php index c243387..b3d8f62 100644 --- a/Announcements/app/Http/Controllers/AnnouncementsController.php +++ b/Announcements/app/Http/Controllers/AnnouncementsController.php @@ -56,10 +56,7 @@ public function getUserAnnouncements(Request $request) ->paginate($request->query('per_page', 20)); } - return response()->json([ - 'message' => 'User announcements retrieved successfully', - 'announcements' => $announcements, - ]); + return apiResponse('User announcements retrieved successfully', $announcements); } #[PathParameter('announcementId', description: 'ID of the announcement to dismiss', type: 'integer')] @@ -68,83 +65,71 @@ public function dismissAnnouncement(Request $request, $announcementId) $user = $request->attributes->get('api_key')->user; $announcement = Announcement::find($announcementId); - if (! $announcement) { - return response()->json(['error' => 'Announcement not found'], 404); + if (!$announcement) { + return apiResponse('Announcement not found', null, false, 404); } if ($announcement->dismissed()->where('user_id', $user->id)->exists()) { - return response()->json(['error' => 'Announcement already dismissed'], 400); + return apiResponse('Announcement already dismissed', null, false, 422); } - if (! $announcement->dismissible) { - return response()->json(['error' => 'Announcement is not dismissible'], 400); + if (!$announcement->dismissible) { + return apiResponse('Announcement is not dismissible', null, false, 422); } $announcement->dismissed()->create([ 'user_id' => $user->id, ]); - return response()->json([ - 'message' => 'Announcement dismissed successfully', - 'announcement' => $announcement, - ]); + return apiResponse('Announcement dismissed successfully', $announcement); } #[QueryParameter('per_page', description: 'Number of announcements per page', type: 'integer', default: 20, example: 10)] public function getAnnouncements(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.announcements') || ! $request->attributes->get('api_key')->can('admin.announcements')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.announcements')) { + return $apiKey->sendNoPermissionResponse(); } - return response()->json([ - 'message' => 'Announcements retrieved successfully', - 'announcements' => Announcement::orderBy('created_at')->with('access')->paginate($request->query('per_page', 20)), - ]); + return apiResponse('Announcements retrieved successfully', Announcement::orderBy('created_at')->with('access')->paginate($request->query('per_page', 20))); } #[PathParameter('announcementId', description: 'ID of the announcement to view', type: 'integer')] public function getAnnouncement(Request $request, $announcementId) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.announcements') || ! $request->attributes->get('api_key')->can('admin.announcements')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.announcements')) { + return $apiKey->sendNoPermissionResponse(); } $announcement = Announcement::findOrFail($announcementId); - return response()->json([ - 'message' => 'Announcement retrieved successfully', - 'announcement' => $announcement, - ]); + return apiResponse('Announcement retrieved successfully', $announcement); } public function createAnnouncement(Request $request) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.announcements.create') || ! $request->attributes->get('api_key')->can('admin.announcements.create')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.announcements.create')) { + return $apiKey->sendNoPermissionResponse(); } $announcement = CreateAnnouncementAction::run($request->all()); - return response()->json([ - 'message' => 'Announcement created successfully', - 'announcement' => $announcement, - ]); + return apiResponse('Announcement created successfully', $announcement); } #[PathParameter('announcementId', description: 'ID of the announcement to update', type: 'integer')] public function updateAnnouncement(Request $request, $announcementId) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.announcements.update') || ! $request->attributes->get('api_key')->can('admin.announcements.update')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.announcements.update')) { + return $apiKey->sendNoPermissionResponse(); } $request->validate([ @@ -158,36 +143,31 @@ public function updateAnnouncement(Request $request, $announcementId) ]); $announcement = Announcement::find($announcementId); - if (! $announcement) { + if (!$announcement) { return response()->json(['error' => 'Announcement not found'], 404); } UpdateAnnouncementAction::run($announcement, $request->all()); - return response()->json([ - 'message' => 'Announcement updated successfully', - 'announcement' => $announcement->fresh(), - ]); + return apiResponse('Announcement updated successfully', $announcement->fresh()); } #[PathParameter('announcementId', description: 'ID of the announcement to delete', type: 'integer')] public function deleteAnnouncement(Request $request, $announcementId) { - $user = $request->attributes->get('api_key')->user; + $apiKey = $request->attributes->get('api_key'); - if (! $user->can('admin.announcements.delete') || ! $request->attributes->get('api_key')->can('admin.announcements.delete')) { - return response()->json(['error' => 'Unauthorized'], 403); + if (!$apiKey->hasPermission('admin.announcements.delete')) { + return $apiKey->sendNoPermissionResponse(); } $announcement = Announcement::find($announcementId); - if (! $announcement) { - return response()->json(['error' => 'Announcement not found'], 404); + if (!$announcement) { + return apiResponse('Announcement not found', null, false, 404); } DeleteAnnouncementAction::run($announcement); - return response()->json([ - 'message' => 'Announcement deleted successfully', - ]); + return apiResponse('Announcement deleted successfully'); } } diff --git a/Announcements/module.json b/Announcements/module.json index e31d00f..32f1272 100644 --- a/Announcements/module.json +++ b/Announcements/module.json @@ -5,7 +5,7 @@ "keywords": ["announcements", "cyanfox", "base"], "authors": ["CyanFox"], "license": "MIT", - "version": "25.08.1", + "version": "2025.10.0", "remote_version_url": "https://raw.githubusercontent.com/CyanFox/Modules/v4/Announcements/module.json", "priority": 0, "providers": [ diff --git a/Announcements/routes/api.php b/Announcements/routes/api.php index ba44ddc..a3ef8d7 100644 --- a/Announcements/routes/api.php +++ b/Announcements/routes/api.php @@ -15,14 +15,14 @@ use Modules\Announcements\app\Http\Controllers\AnnouncementsController; Route::group(['middleware' => ['api_key'], 'prefix' => 'v1/announcements'], function () { - Route::get('/', [AnnouncementsController::class, 'getUserAnnouncements'])->name('Get User Announcements'); - Route::patch('dismiss/{announcementId}', [AnnouncementsController::class, 'dismissAnnouncement'])->name('Dismiss Announcement'); + Route::get('/', [AnnouncementsController::class, 'getUserAnnouncements'])->name('announcements.user.view'); + Route::patch('dismiss/{announcementId}', [AnnouncementsController::class, 'dismissAnnouncement'])->name('announcements.dismiss'); Route::prefix('admin')->group(function () { - Route::get('/', [AnnouncementsController::class, 'getAnnouncements'])->name('Get Announcements'); - Route::post('/', [AnnouncementsController::class, 'createAnnouncement'])->name('Create Announcement'); - Route::get('{announcementId}', [AnnouncementsController::class, 'getAnnouncement'])->name('Get specific Announcement'); - Route::delete('{announcementId}', [AnnouncementsController::class, 'deleteAnnouncement'])->name('Delete Announcement'); - Route::put('{announcementId}', [AnnouncementsController::class, 'updateAnnouncement'])->name('Update Announcement'); + Route::get('/', [AnnouncementsController::class, 'getAnnouncements'])->name('announcements'); + Route::post('/', [AnnouncementsController::class, 'createAnnouncement'])->name('announcements.create'); + Route::get('{announcementId}', [AnnouncementsController::class, 'getAnnouncement'])->name('announcements.view'); + Route::delete('{announcementId}', [AnnouncementsController::class, 'deleteAnnouncement'])->name('announcements.delete'); + Route::put('{announcementId}', [AnnouncementsController::class, 'updateAnnouncement'])->name('announcements.update'); }); }); diff --git a/Auth/app/Http/Controllers/AccountController.php b/Auth/app/Http/Controllers/AccountController.php index 7ab59b1..702447b 100644 --- a/Auth/app/Http/Controllers/AccountController.php +++ b/Auth/app/Http/Controllers/AccountController.php @@ -3,6 +3,7 @@ namespace Modules\Auth\Http\Controllers; use Dedoc\Scramble\Attributes\Group; +use Dedoc\Scramble\Attributes\PathParameter; use Dedoc\Scramble\Attributes\QueryParameter; use Illuminate\Http\Request; use Illuminate\Support\Carbon; @@ -18,22 +19,20 @@ public function getUser(Request $request) $user->load('roles:id,name', 'permissions:id,name'); - return response()->json([ - 'message' => 'Account retrieved successfully', - 'user' => array_merge( + return apiResponse('Account retrieved successfully', + array_merge( $user->toArray(), [ - 'roles' => $user->roles->map(fn ($role) => [ + 'roles' => $user->roles->map(fn($role) => [ 'id' => $role->id, 'name' => $role->name, ]), - 'permissions' => $user->permissions->map(fn ($perm) => [ + 'permissions' => $user->permissions->map(fn($perm) => [ 'id' => $perm->id, 'name' => $perm->name, ]), ] - ), - ]); + )); } public function updateAccount(Request $request) @@ -42,7 +41,7 @@ public function updateAccount(Request $request) $request->validate([ 'first_name' => 'nullable|string|max:255', 'last_name' => 'nullable|string|max:255', - 'username' => 'nullable|string|max:255|unique:users,username,'.$user->id, + 'username' => 'nullable|string|max:255|unique:users,username,' . $user->id, 'theme' => 'nullable|string|in:light,dark', 'language' => 'nullable|string|in:en,de', 'custom_avatar_url' => 'nullable|url|max:2048', @@ -57,10 +56,33 @@ public function updateAccount(Request $request) 'custom_avatar_url', ])); - return response()->json([ - 'message' => 'Account updated successfully', - 'user' => $user, + return apiResponse('Account updated successfully', $user); + } + + public function hasPermission(Request $request) + { + $user = $request->attributes->get('api_key')->user; + + $request->validate([ + 'permission' => 'required|string|exists:permissions,name', + ]); + + return apiResponse('Permission check completed successfully', [ + 'has_permission' => $user->can($request->input('permission')), + ]); + } + + public function uploadAvatar(Request $request) + { + $user = $request->attributes->get('api_key')->user; + + $request->validate([ + 'avatar' => 'required|image:allow_svg|max:10000', ]); + + $request->file('avatar')->storeAs('avatars', $user->id.'.png', 'public'); + + return apiResponse('Avatar uploaded successfully', $user); } #[QueryParameter('per_page', description: 'Number of activity entries per page', type: 'integer', default: 20, example: 10)] @@ -72,9 +94,8 @@ public function getActivity(Request $request) ->orderBy('created_at', 'desc') ->paginate($request->query('per_page', 20)); - return response()->json([ - 'message' => 'Activity retrieved successfully', - 'activity_log' => $activityLog->map(function (Activity $activity) { + return apiResponse('Activity retrieved successfully', + $activityLog->map(function (Activity $activity) { $properties = json_decode($activity->properties, true) ?? []; return [ @@ -86,8 +107,7 @@ public function getActivity(Request $request) 'old_values' => $properties['old'] ?? [], 'new_values' => $properties['attributes'] ?? [], ]; - }), - ]); + })); } #[QueryParameter('per_page', description: 'Number of session entries per page', type: 'integer', default: 20, example: 10)] @@ -99,16 +119,131 @@ public function getSessions(Request $request) ->orderBy('last_activity', 'desc') ->paginate($request->query('per_page', 20)); - return response()->json([ - 'message' => 'Sessions retrieved successfully', - 'sessions' => $sessions->map(function ($session) { + return apiResponse('Sessions retrieved successfully', + $sessions->map(function ($session) { return [ 'id' => $session->id, 'ip_address' => $session->ip_address, 'user_agent' => $session->user_agent, 'last_activity' => Carbon::createFromTimestamp($session->last_activity)->toIso8601String(), ]; - }), + })); + } + + public function revokeSessions(Request $request) + { + $user = $request->attributes->get('api_key')->user; + + $user->revokeOtherSessions(); + + return apiResponse('All sessions revoked successfully'); + } + + #[PathParameter('sessionId', description: 'ID of the session to revoke', type: 'string', example: 'PHvAlcFhPKbwTAUPNbFsIlN4cnsVg9N6Dp1NbpEM')] + public function revokeSession(Request $request, $sessionId) + { + $user = $request->attributes->get('api_key')->user; + + $session = $user->sessions()->where('id', $sessionId)->first(); + + if (!$session) { + return apiResponse('Session not found', null, false, 404); + } + + $session->delete(); + + return apiResponse('Session revoked successfully'); + } + + public function activateTwoFactor(Request $request) + { + $user = $request->attributes->get('api_key')->user; + + if ($user->two_factor_enabled) { + return apiResponse('Two-factor authentication is already enabled', null, false, 400); + } + + $recoveryCodes = $user->generateRecoveryCodes(); + + UpdateUserAction::run($user, [ + 'two_factor_enabled' => true, + ]); + + $user->revokeOtherSessions(); + + return apiResponse('Two-factor authentication enabled successfully', [ + 'two_factor_secret' => decrypt($user->two_factor_secret), + 'two_factor_qr_code_url' => 'data:image/svg+xml;base64,' . $user->getTwoFactorImage(), + 'recovery_codes' => $recoveryCodes, + ]); + } + + public function disableTwoFactor(Request $request) + { + $user = $request->attributes->get('api_key')->user; + + if (!$user->two_factor_enabled) { + return apiResponse('Two-factor authentication is not enabled', null, false, 400); + } + + UpdateUserAction::run($user, [ + 'two_factor_secret' => null, + 'two_factor_enabled' => false, ]); + + $user->generateTwoFASecret(); + $user->recoveryCodes()->delete(); + + return apiResponse('Two-factor authentication disabled successfully'); } + + #[QueryParameter('use_recovery_code', description: 'Set to true if you are using a recovery code instead of a 2FA code', type: 'boolean', default: false, example: false)] + public function verifyTwoFactorCode(Request $request) + { + $user = $request->attributes->get('api_key')->user; + $useRecoveryCode = $request->query('use_recovery_code', false); + + if (!$user->two_factor_enabled) { + return apiResponse('Two-factor authentication is not enabled', null, false, 400); + } + + $request->validate([ + 'code' => 'required|string', + ]); + + $code = $request->input('code'); + + if ($user->checkTwoFACode($code, $useRecoveryCode)) { + return apiResponse('Two-factor or recovery code is valid'); + } + + return apiResponse('Invalid two-factor or recovery code', null, false, 400); + } + + public function regenerateRecoveryCodes(Request $request) + { + $user = $request->attributes->get('api_key')->user; + + if (!$user->two_factor_enabled) { + return apiResponse('Two-factor authentication is not enabled', null, false, 400); + } + + $recoveryCodes = $user->generateRecoveryCodes(); + + return apiResponse('Recovery codes regenerated successfully', $recoveryCodes); + } + + public function deleteAccount(Request $request) + { + $user = $request->attributes->get('api_key')->user; + + if (!settings('auth.profile.enable.delete_account')) { + return apiResponse('Account deletion is disabled', null, false, 403); + } + + $user->delete(); + + return apiResponse('Account deleted successfully'); + } + } diff --git a/Auth/app/Http/Controllers/AuthController.php b/Auth/app/Http/Controllers/AuthController.php new file mode 100644 index 0000000..e944ba1 --- /dev/null +++ b/Auth/app/Http/Controllers/AuthController.php @@ -0,0 +1,211 @@ +route('username'))->first(); + + if (!$user) { + return apiResponse('User not found', null, false, 404); + } + + return apiResponse('User found', [ + 'username' => $user->username, + 'avatar' => $user->avatar(), + ]); + } + + public function login(Request $request) + { + $request->validate([ + 'username' => 'required|string', + 'password' => 'required|string', + 'api_key_name' => 'nullable|string', + 'two_factor_code' => 'nullable|string', + 'is_recovery_code' => 'nullable|boolean', + ]); + + if ($request->filled('two_factor_code') || $request->input('is_recovery_code', false)) { + return $this->checkTwoFactorCode($request); + } + + if (!auth()->attempt($request->only('username', 'password'))) { + activity() + ->performedOn($this->user) + ->causedByAnonymous() + ->log('api.auth.login_failed'); + return apiResponse('Invalid credentials', null, false, 401); + } + + $user = auth()->user(); + + if ($user->disabled) { + activity() + ->performedOn($this->user) + ->causedByAnonymous() + ->log('api.auth.login_failed'); + + auth()->logout(); + return apiResponse('User account is disabled', null, false, 403); + } + + if ($user->two_factor_enabled) { + auth()->logout(); + return apiResponse('Two-factor authentication required', ['two_factor' => true], false, 403); + } + + return $this->generateLoginToken($user, $request->input('api_key_name')); + } + + public function checkTwoFactorCode(Request $request) + { + $request->validate([ + 'username' => 'required|string', + 'password' => 'required|string', + 'two_factor_code' => 'required|string', + 'is_recovery_code' => 'nullable|boolean', + 'api_key_name' => 'nullable|string', + ]); + + if (!auth()->attempt($request->only('username', 'password'))) { + return apiResponse('Invalid credentials', null, false, 401); + } + + $user = auth()->user(); + + if ($user->disabled) { + auth()->logout(); + return apiResponse('User account is disabled', null, false, 403); + } + + if (!$user->two_factor_enabled) { + return apiResponse('Two-factor authentication not enabled', null, false, 400); + } + + if ($request->input('is_recovery_code', false)) { + foreach ($user->recoveryCodes as $recoveryCode) { + if (Hash::check($request->input('two_factor_code'), $recoveryCode->code)) { + $recoveryCode->delete(); + if (!Session::where('user_id', $user->id) + ->where('ip_address', request()->ip()) + ->exists()) { + $mail = new NewSessionMail($user->email, $user->username, $user->first_name, $user->last_name); + + Mail::send($mail); + } + + activity() + ->performedOn($user) + ->causedByAnonymous() + ->log('api.auth.login.recovery_code'); + + return $this->generateLoginToken($user, $request->input('api_key_name')); + } + } + + activity() + ->performedOn($user) + ->causedByAnonymous() + ->log('api.auth.login.recovery_code.failed'); + + return apiResponse('Invalid recovery code', null, false, 401); + } + + if ($user->checkTwoFACode($request->input('two_factor_code'))) { + if (!Session::where('user_id', $user->id) + ->where('ip_address', request()->ip()) + ->exists() && settings('auth.emails.new_session.enabled', config('auth.emails.new_session.enabled'))) { + $mail = new NewSessionMail($user->email, $user->username, $user->first_name, $user->last_name); + + Mail::send($mail); + } + + activity() + ->performedOn($user) + ->causedByAnonymous() + ->log('api.auth.login.two_factor'); + + return $this->generateLoginToken($user, $request->input('api_key_name')); + } + + activity() + ->performedOn($user) + ->causedByAnonymous() + ->log('api.auth.login.two_factor.failed'); + + return apiResponse('Invalid two-factor code', null, false, 401); + } + + public function logout(Request $request) + { + $request->attributes->get('api_key')->delete(); + + return apiResponse('Logged out'); + } + + private function generateLoginToken($user, $keyName = null, $message = 'Login successful'): JsonResponse + { + $key = Str::random(32); + + $apiKey = $user->apiKeys()->create([ + 'name' => $keyName ?? 'API Key ' . formatDateTime(now()), + 'key' => Hash::make($key), + 'connected_device' => true, + ]); + + return apiResponse($message, [ + 'user' => $user, + 'api_key_id' => $apiKey->id, + 'api_key' => $apiKey->id . '-' . $key, + ]); + } + + public function register(Request $request) + { + $request->validate([ + 'first_name' => 'nullable', + 'last_name' => 'nullable', + 'email' => 'required|email|unique:users,email', + 'username' => 'required|unique:users,username', + 'password' => ['required', new Password], + ], [ + 'email.unique' => __('auth::register.email_unique'), + 'username.unique' => __('auth::register.username_unique'), + ]); + + if (!settings('auth.register.enabled')) { + return apiResponse('Registration is disabled', null, false, 403); + } + + $user = CreateUserAction::run([ + 'first_name' => $request->input('first_name'), + 'last_name' => $request->input('last_name'), + 'email' => $request->input('email'), + 'username' => $request->input('username'), + 'password' => Hash::make($request->input('password')), + ]); + + activity() + ->performedOn($user) + ->causedBy($user) + ->log('api.auth.register'); + + return $this->generateLoginToken($user, $request->input('api_key_name'), 'Registration successful'); + } +} diff --git a/Auth/app/Http/Controllers/UnsplashController.php b/Auth/app/Http/Controllers/UnsplashController.php new file mode 100644 index 0000000..74d6eda --- /dev/null +++ b/Auth/app/Http/Controllers/UnsplashController.php @@ -0,0 +1,36 @@ +hasMany(ApiKeyPermission::class); } + public function hasPermission($permission) + { + if (!$this->user->can($permission) || !$this->can($permission)) { + return false; + } + return true; + } + public function can($permission) { return ApiKeyPermission::where('api_key_id', $this->id) @@ -51,12 +59,17 @@ public function can($permission) ->exists(); } + public function sendNoPermissionResponse() + { + return apiResponse('Unauthorized', null, false, 403); + } + public function getActivitylogOptions(): LogOptions { return LogOptions::defaults() ->logExcept($this->hidden) ->setDescriptionForEvent(function ($eventName) { - return 'auth.user.api_keys.'.$eventName; + return 'auth.user.api_keys.' . $eventName; }); } diff --git a/Auth/app/Providers/AuthServiceProvider.php b/Auth/app/Providers/AuthServiceProvider.php index ed0fc5f..fe2b817 100755 --- a/Auth/app/Providers/AuthServiceProvider.php +++ b/Auth/app/Providers/AuthServiceProvider.php @@ -112,12 +112,6 @@ public function boot(): void */ public function register(): void { - Config::set('scramble.api_path', 'api/v1'); - Config::set('scramble.ui.theme', 'dark'); - Config::set('scramble.ui.hide_try_it', true); - Config::set('scramble.info.version', ''); - Config::set('scramble.middleware', ['auth', 'web']); - $this->app->register(EventServiceProvider::class); $this->app->register(RouteServiceProvider::class); } diff --git a/Auth/app/Traits/WithConfirmation.php b/Auth/app/Traits/WithConfirmation.php index 2316ddf..0a0009f 100755 --- a/Auth/app/Traits/WithConfirmation.php +++ b/Auth/app/Traits/WithConfirmation.php @@ -56,7 +56,18 @@ public function needsPasswordConfirmation() public function method(string $callable, ...$args): static { - $this->confirmationData['event'] = $callable.'('.implode(', ', $args).')'; + $this->confirmationData['event'] = $callable . '(' . implode(', ', $args) . ')'; + + return $this; + } + + public function dispatchEvent(string $to, string $event, ...$args): static + { + $this->confirmationData['event'] = [ + 'to' => $to, + 'event' => $event, + 'args' => $args, + ]; return $this; } @@ -80,10 +91,24 @@ public function send(): void #[On('internal.confirmation.confirmed')] public function handleConfirmation($event): void { - if (preg_match('/^(\w+)\((.*)\)$/', $event, $matches)) { - $methodName = $matches[1]; - $arguments = array_map('trim', explode(',', $matches[2])); - call_user_func_array([$this, $methodName], $arguments); + if (is_array($event)) { + if (isset($event['to'], $event['event'])) { + $to = $event['to']; + $eventName = $event['event']; + $arguments = $event['args'] ?? []; + $this->dispatch($eventName, ...$arguments)->to($to); + } elseif (isset($event['class'], $event['method'])) { + $class = $event['class']; + $method = $event['method']; + $arguments = $event['args'] ?? []; + call_user_func_array([app($class), $method], $arguments); + } + } elseif (is_string($event)) { + if (preg_match('/^([a-zA-Z0-9_]+)\((.*)\)$/', $event, $matches)) { + $method = $matches[1]; + $args = array_map('trim', explode(',', $matches[2])); + call_user_func_array([$this, $method], $args); + } } } } diff --git a/Auth/app/helpers.php b/Auth/app/helpers.php index 334f8ec..102d763 100755 --- a/Auth/app/helpers.php +++ b/Auth/app/helpers.php @@ -1,5 +1,6 @@ boolean('connected_device')->default(false)->after('key'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('api_keys', function (Blueprint $table) { + $table->dropColumn('connected_device'); + }); + } +}; diff --git a/Auth/lang/de/profile.php b/Auth/lang/de/profile.php index e80f03e..09ba481 100755 --- a/Auth/lang/de/profile.php +++ b/Auth/lang/de/profile.php @@ -10,6 +10,7 @@ 'password' => 'Passwort', 'passkeys' => 'Passkeys', 'activity' => 'Aktivitäten', + 'connected_devices' => 'Verknüpfte Geräte' ], 'notifications' => [ diff --git a/Auth/lang/en/profile.php b/Auth/lang/en/profile.php index 08a32f1..19ee0ae 100755 --- a/Auth/lang/en/profile.php +++ b/Auth/lang/en/profile.php @@ -10,6 +10,7 @@ 'password' => 'Password', 'passkeys' => 'Passkeys', 'activity' => 'Activity', + 'connected_devices' => 'Connected Devices', ], 'notifications' => [ diff --git a/Auth/module.json b/Auth/module.json index 41b51c1..878754a 100755 --- a/Auth/module.json +++ b/Auth/module.json @@ -5,7 +5,7 @@ "keywords": ["auth", "cyanfox", "base"], "authors": ["CyanFox"], "license": "MIT", - "version": "25.08.2", + "version": "2025.10.0", "remote_version_url": "https://raw.githubusercontent.com/CyanFox/Modules/v4/Auth/module.json", "priority": 100, "settings_page": "admin.settings.auth", diff --git a/Auth/resources/views/livewire/account/profile.blade.php b/Auth/resources/views/livewire/account/profile.blade.php index 27ab688..eb66bb8 100755 --- a/Auth/resources/views/livewire/account/profile.blade.php +++ b/Auth/resources/views/livewire/account/profile.blade.php @@ -434,7 +434,7 @@ class="flex items-center rounded-radius p-1 text-on-surface hover:text-primary d - @foreach(auth()->user()->apiKeys()->with('permissions.permission')->get() as $apiKey) + @foreach(auth()->user()->apiKeys()->with('permissions.permission')->where('connected_device', false)->get() as $apiKey) {{ $apiKey->name }} diff --git a/Auth/routes/api.php b/Auth/routes/api.php index eca3d28..6ba05e4 100755 --- a/Auth/routes/api.php +++ b/Auth/routes/api.php @@ -2,6 +2,8 @@ use Illuminate\Support\Facades\Route; use Modules\Auth\Http\Controllers\AccountController; +use Modules\Auth\Http\Controllers\AuthController; +use Modules\Auth\Http\Controllers\UnsplashController; /* *-------------------------------------------------------------------------- @@ -14,13 +16,39 @@ * */ -Route::middleware(['api_key'])->prefix('v1')->group(function () { - Route::get('/', fn () => response()->json(['message' => 'Welcome to the API! Docs can be found under /docs/api'])); +Route::group(['middleware' => ['api_key'], 'prefix' => 'v1', 'name' => 'api.'], function () { + Route::get('/', fn() => response()->json(['message' => 'Welcome to the API! Docs can be found under /docs/api'])); Route::group(['prefix' => 'account'], function () { - Route::get('/', [AccountController::class, 'getUser'])->name('Get User'); - Route::put('update', [AccountController::class, 'updateAccount'])->name('Update Account'); - Route::get('activity', [AccountController::class, 'getActivity'])->name('Get Activity'); - Route::get('sessions', [AccountController::class, 'getSessions'])->name('Get Sessions'); + Route::get('/', [AccountController::class, 'getUser'])->name('account.user'); + Route::delete('/', [AccountController::class, 'deleteAccount'])->name('account.delete'); + Route::put('/', [AccountController::class, 'updateAccount'])->name('account.update'); + Route::get('permission', [AccountController::class, 'hasPermission'])->name('account.user.permission'); + Route::get('activity', [AccountController::class, 'getActivity'])->name('account.activity'); + Route::get('sessions', [AccountController::class, 'getSessions'])->name('account.sessions'); + Route::post('avatar', [AccountController::class, 'uploadAvatar'])->name('account.avatar.upload'); + + Route::group(['prefix' => 'twofa'], function () { + Route::post('enable', [AccountController::class, 'activateTwoFactor'])->name('account.two-fa.enable'); + Route::post('disable', [AccountController::class, 'disableTwoFactor'])->name('account.two-fa.disable'); + Route::post('verify', [AccountController::class, 'verifyTwoFactorCode'])->name('account.two-fa.verify'); + Route::post('regenerate', [AccountController::class, 'regenerateRecoveryCodes'])->name('account.two-fa.regenerate'); + }); + }); + + Route::group(['prefix' => 'auth'], function () { + Route::post('logout', [AuthController::class, 'logout'])->name('auth.logout'); }); }); + +Route::group(['prefix' => 'v1/auth', 'name' => 'api.'], function () { + Route::get('lookup/{username}', [AuthController::class, 'lookupUser'])->name('auth.lookup')->middleware('throttle:10,1'); + Route::post('login', [AuthController::class, 'login'])->name('auth.login')->middleware('throttle:10,1'); + Route::post('register', [AuthController::class, 'register'])->name('auth.register')->middleware('throttle:5,1'); +}); + +Route::group(['prefix' => 'v1/unsplash', 'name' => 'api.'], function () { + Route::get('css', [UnsplashController::class, 'getRandomBackgroundCss'])->name('unsplash.css')->middleware('throttle:50,1'); + Route::get('url', [UnsplashController::class, 'getRandomBackgroundUrl'])->name('unsplash.url')->middleware('throttle:50,1'); + Route::get('utm', [UnsplashController::class, 'getUtmSource'])->name('unsplash.utm')->middleware('throttle:50,1'); +}); diff --git a/Auth/routes/web.php b/Auth/routes/web.php index cf123d6..e834fcb 100755 --- a/Auth/routes/web.php +++ b/Auth/routes/web.php @@ -1,5 +1,6 @@