*/ use HasFactory, Notifiable; /** * Check if user is an admin. */ public function isAdmin(): bool { return $this->role === 'admin' || $this->hasRole('admin'); } /** * Check if the user has a specific role by name. */ public function hasRole(string $roleName): bool { if ($this->roles->isEmpty()) { $defaultRoleName = \App\Models\Setting::get('default_role', 'Developer'); return strtolower($roleName) === strtolower($defaultRoleName); } return $this->roles->contains(function ($r) use ($roleName) { return strtolower($r->name) === strtolower($roleName); }); } /** * Get the roles assigned to this user. */ public function roles() { return $this->belongsToMany(Role::class, 'role_user'); } /** * Get the app overrides (allow/deny) for this user. */ public function overrides() { return $this->hasMany(UserAppOverride::class); } /** * Get the personal custom apps for this user. */ public function personalApps() { return $this->hasMany(PersonalApp::class); } /** * Get the authorized apps for this user, computed from roles and overrides. */ public function authorizedApps() { if ($this->isAdmin()) { return App::orderBy('name', 'asc')->get(); } $roleIds = $this->roles()->pluck('roles.id')->toArray(); // If no roles are assigned, fallback to configured default role first if (empty($roleIds)) { $defaultRoleName = \App\Models\Setting::get('default_role', 'Developer'); $defaultRole = \App\Models\Role::where('name', $defaultRoleName)->first(); if ($defaultRole) { $roleIds = [$defaultRole->id]; } } // Get apps associated with user's roles $roleAppIds = \DB::table('app_role') ->whereIn('role_id', $roleIds) ->pluck('app_id') ->toArray(); // If still no roles/apps resolved, user gets default access to Outlook email and Drive apps if registered if (empty($roleAppIds)) { $defaultAppIds = App::where(function ($query) { $query->whereRaw('LOWER(name) LIKE ?', ['%outlook%']) ->orWhereRaw('LOWER(name) LIKE ?', ['%mail%']) ->orWhereRaw('LOWER(name) LIKE ?', ['%email%']) ->orWhereRaw('LOWER(name) LIKE ?', ['%drive%']) ->orWhereRaw('LOWER(name) LIKE ?', ['%onedrive%']) ->orWhereRaw('LOWER(tag) LIKE ?', ['%outlook%']) ->orWhereRaw('LOWER(tag) LIKE ?', ['%mail%']) ->orWhereRaw('LOWER(tag) LIKE ?', ['%email%']) ->orWhereRaw('LOWER(tag) LIKE ?', ['%drive%']) ->orWhereRaw('LOWER(tag) LIKE ?', ['%onedrive%']); })->pluck('id')->toArray(); $roleAppIds = array_unique(array_merge($roleAppIds, $defaultAppIds)); } // Get user overrides $overrides = $this->overrides()->get(); $allowedAppIds = $overrides->where('type', 'allow')->pluck('app_id')->toArray(); $deniedAppIds = $overrides->where('type', 'deny')->pluck('app_id')->toArray(); // Compute final allowed app IDs: (Role Apps + Allowed Overrides) - Denied Overrides $finalAppIds = array_diff( array_unique(array_merge($roleAppIds, $allowedAppIds)), $deniedAppIds ); return App::whereIn('id', $finalAppIds)->orderBy('name', 'asc')->get(); } /** * Get the attributes that should be cast. * * @return array */ protected function casts(): array { return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', ]; } }