Issues (144)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

app/Device.php (1 issue)

1
<?php
2
3
namespace App;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Database\Eloquent\SoftDeletes;
7
use Carbon\Carbon;
8
use Illuminate\Support\Facades\Auth;
9
use Spatie\Activitylog\Traits\LogsActivity;
10
11
class Device extends Model
12
{
13
    use SoftDeletes;
14
    use LogsActivity;
15
    //use CausesActivity;
16
    
17
    /**
18
     * The attributes that should be mutated to dates.
19
     *
20
     * @var array
21
     */
22
    protected $dates = [
23
        'deleted_at',
24
        'last_network_update_at'
25
    ];
26
    
27
    /**
28
     * The attributes that should be hidden for arrays.
29
     *
30
     * @var array
31
     */
32
    protected $hidden = [ 'token' ];
33
    
34
    /**
35
     * The attributes that are mass assignable.
36
     *
37
     * @var array
38
     */
39
    protected $fillable = [
40
        'name', 'location_id', 'uuid', 'version', 'hostname', 'ip', 'mac_address', 
41
        'time', 'cover_command', 'cover_status', 'error_msg', 'update_rate',
42
        'image_rate', 'sensor_rate', 'open_time', 'close_time', 'last_network_update_at',
43
    ];
44
    
45
    /**
46
     * The attributes to ignore in the Activity Log
47
     *
48
     * @var array
49
     */
50
    protected static $ignoreChangedAttributes = [ 'updated_at', 'last_network_update_at' ];
51
    
52
    /**
53
     * The attributes to log in the Activity Log
54
     *
55
     * @var array
56
     */
57
    protected static $logAttributes = [
58
        'name', 'location_id', 'uuid', 'version', 'hostname', 'ip', 'mac_address', 
59
        'time', 'cover_command', 'cover_status', 'error_msg',
60
        'update_rate', 'image_rate', 'sensor_rate', 'open_time', 'close_time'
61
    ];
62
    
63
    /**
64
     * Only log those that have actually changed after the update.
65
     *
66
     * @var array
67
     */
68
    protected static $logOnlyDirty = true;
69
    
70
    /**
71
     * Update the updated_at and created_at timestamps?
72
     *
73
     * @var array
74
     */
75
    public $timestamps = true;
76
    
77
    /**
78
     * Get the location for the device
79
     */
80
    public function location()
81
    {
82
        return $this->belongsTo('App\Location', 'location_id');
83
    }
84
    
85
    /**
86
     * Get the site for the device using model accessor
87
     */
88
    public function getSiteAttribute()
89
    {
90
        return $this->location->site ?? (object) [ ];
91
    }
92
    
93
    /**
94
     * Accessor: Get the open time of the device converted to hours and minutes
95
     * If it is a device accessing the time use UTC
96
     * If it is a user accessing the time use their preferred timezone
97
     *
98
     * @param  string $value
99
     * @return string
100
     */
101 View Code Duplication
    public function getOpenTimeAttribute($value)
102
    {
103
        $time = new Carbon($value, 'UTC');
104
        
105
        //If the user is logged in then use there preferred timezone
106
        if (Auth::check()) {
107
                    $time = $time->setTimezone(Auth::user()->timezone);
108
        }
109
110
        return $time->format('H:i');
111
    }
112
    
113
    /**
114
     * Accessor: Get the open time of the device converted to the users preferred time and
115
     * converted to a user friendly format of h:i a
116
     *
117
     * @return string
118
     */
119 View Code Duplication
    public function getOpenTimeHumanAttribute()
120
    {
121
        $time = new Carbon($this->attributes[ 'open_time' ], 'UTC');
122
        $time = $time->setTimezone(Auth::user()->timezone);
123
        
124
        return $time->format('h:i a');
125
    }
126
    
127
    /**
128
     * Accessor: Get the close time of the device converted to hours and minutes
129
     * If it is a device accessing the time use UTC
130
     * If it is a user accessing the time use their preferred timezone
131
     *
132
     * @param  string $value
133
     * @return string
134
     */
135 View Code Duplication
    public function getCloseTimeAttribute($value)
136
    {
137
        $time = new Carbon($value, 'UTC');
138
    
139
        //If the user is logged in then use there preferred timezone
140
        if (Auth::check()) {
141
                    $time = $time->setTimezone(Auth::user()->timezone);
142
        }
143
        
144
        return $time->format('H:i');
145
    }
146
    
147
    /**
148
     * Accessor: Get the close time of the device converted to the users preferred time and
149
     * converted to a user friendly format of h:i a
150
     *
151
     * @return string
152
     */
153 View Code Duplication
    public function getCloseTimeHumanAttribute()
154
    {
155
        $time = new Carbon($this->attributes[ 'close_time' ], 'UTC');
156
        $time = $time->setTimezone(Auth::user()->timezone);
157
        
158
        return $time->format('h:i a');
159
    }
160
    
161
    /**
162
     * Set the open time to UTC
163
     * If it is a device saving the time use UTC
164
     * If it is a user saving the time use their preferred timezone
165
     *
166
     * @param  string  $value
167
     * @return void
168
     */
169 View Code Duplication
    public function setOpenTimeAttribute($value)
170
    {
171
        //If the user is logged in then use there preferred timezone
172
        if (Auth::check())
173
        {
174
            $time = new Carbon($value, Auth::user()->timezone);
175
            $time = $time->setTimezone('UTC');
176
        } else {
177
                    $time = new Carbon($value, 'UTC');
178
        }
179
        
180
        $this->attributes[ 'open_time' ] = $time->format('H:i:s');
181
    }
182
    
183
    /**
184
     * Set the close time to UTC
185
     * If it is a device saving the time use UTC
186
     * If it is a user saving the time use their preferred timezone
187
     *
188
     * @param  string  $value
189
     * @return void
190
     */
191 View Code Duplication
    public function setCloseTimeAttribute($value)
192
    {
193
        //If the user is logged in then use there preferred timezone
194
        if (Auth::check())
195
        {
196
            $time = new Carbon($value, Auth::user()->timezone);
197
            $time = $time->setTimezone('UTC');
198
        } else {
199
                    $time = new Carbon($value, 'UTC');
200
        }
201
        
202
        $this->attributes[ 'close_time' ] = $time->format('H:i:s');
203
    }
204
    
205
    /**
206
     * Accessor: Get the last time the server received an update call from the device in seconds/minutes/hours since
207
     * update or converted to user friendly readable format.
208
     * If the time is less then a day old then display time since it last updated
209
     * If the time is greater then a day old then display the time in the format of Month day, year 12hour:mins am/pm
210
     * and using the user's preferred timezone
211
     *
212
     * @return string
213
     */
214 View Code Duplication
    public function getLastNetworkUpdateAtHumanAttribute()
215
    {
216
        if ($this->last_network_update_at->diffInDays() > 0) {
217
                    return $this->last_network_update_at->setTimezone(Auth::user()->timezone)->format('M d, Y h:i a');
218
        } else {
219
                    return $this->last_network_update_at->diffForHumans();
220
        }
221
    }
222
    
223
    /**
224
     * Accessor: Get the devices last update time in seconds/minutes/hours since update or converted to user friendly
225
     * readable format.
226
     * If the time is less then a day old then display time since it last update
227
     * If the time is greater then a day old then display the time in the format of Month day, year 12hour:mins am/pm
228
     * and using the user's preferred timezone
229
     *
230
     *
231
     * @return string
232
     */
233 View Code Duplication
    public function getUpdatedAtHumanAttribute()
234
    {
235
        if ($this->updated_at->diffInDays() > 0) {
236
                    return $this->updated_at->setTimezone(Auth::user()->timezone)->format('M d, Y h:i a');
237
        } else {
238
                    return $this->updated_at->diffForHumans();
239
        }
240
    }
241
    
242
    /**
243
     * Accessor: Get the devices creation time in seconds/minutes/hours since creation or converted to user friendly
244
     * readable format.
245
     * If the time is less then a day old then display time since its creation
246
     * If the time is greater then a day old then display the time in the format of Month day, year 12hour:mins am/pm
247
     * and using the user's preferred timezone
248
     *
249
     * @return string
250
     */
251 View Code Duplication
    public function getCreatedAtHumanAttribute()
252
    {
253
        if ($this->created_at->diffInDays() > 0) {
254
                    return $this->created_at->setTimezone(Auth::user()->timezone)->format('M d, Y h:i a');
255
        } else {
256
                    return $this->created_at->diffForHumans();
257
        }
258
    }
259
    
260
    /**
261
     * Accessor: Get the devices deletion time in seconds/minutes/hours since creation or converted to user friendly
262
     * readable format.
263
     * If the time is less then a day old then display time since its deletion
264
     * If the time is greater then a day old then display the time in the format of Month day, year 12hour:mins am/pm
265
     * and using the user's preferred timezone
266
     *
267
     * @return string
268
     */
269 View Code Duplication
    public function getDeletedAtHumanAttribute()
270
    {
271
        if ($this->deleted_at->diffInDays() > 0) {
272
            return $this->deleted_at->setTimezone(Auth::user()->timezone)->format('M d, Y h:i a');
273
        } else {
274
            return $this->deleted_at->diffForHumans();
275
        }
276
    }
277
    
278
    /**
279
     * Scope a query to only include devices belonging to a given location
280
     *
281
     * @param \Illuminate\Database\Eloquent\Builder $query
282
     * @param int $location_id
283
     * @return \Illuminate\Database\Eloquent\Builder
284
     */
285
    public function scopeByLocation($query, $location_id)
286
    {
287
        return $query->where('location_id', $location_id);
288
    }
289
    
290
    /**
291
     * Scope a query to limit the included columns to only include what is publicly needed to be displayed on the
292
     * dashboard
293
     *
294
     * @param \Illuminate\Database\Eloquent\Builder $query
295
     * @return \Illuminate\Database\Eloquent\Builder
296
     */
297
    public function scopePublicDashData($query)
298
    {
299
        return $query->select([
0 ignored issues
show
Bug Best Practice introduced by
The expression return $query->select(ar... as image_updated_at')) also could return the type Illuminate\Database\Query\Builder which is incompatible with the documented return type Illuminate\Database\Eloquent\Builder.
Loading history...
300
            'devices.id',
301
            'name',
302
            'location_id',
303
            'cover_command',
304
            'cover_status',
305
            'open_time',
306
            'close_time',
307
            'update_rate',
308
            'image_rate',
309
            'sensor_rate',
310
            'last_network_update_at',
311
            'image.updated_at as image_updated_at',
312
        ]);
313
    }
314
    
315
    /**
316
     * Create a new API token for the device.
317
     */
318
    public function generateToken()
319
    {
320
        $this->token = str_random(60);
321
        $this->save();
322
        
323
        return $this->token;
324
    }
325
    
326
    /**
327
     * Get a device by uuid
328
     *
329
     * @param string $uuid
330
     * @return Device|Illuminate\Database\Eloquent\Model
331
     */
332
    public static function getDeviceByUUID($uuid)
333
    {
334
        return self::where('uuid', $uuid)->first();
335
    }
336
    
337
    /**
338
     * Get the deviceimage record associated with the device.
339
     */
340
    public function image()
341
    {
342
        return $this->hasOne('App\Deviceimage');
343
    }
344
    
345
346
    /**
347
     * Get the sensors associated with the device.
348
     */
349
    public function sensors()
350
    {
351
        return $this->hasMany('App\Sensor');
352
    }
353
    
354
    /**
355
     * Get the sensor data associated with the device.
356
     */
357
    public function data()
358
    {
359
        return $this->hasManyThrough('App\SensorData', 'App\Sensor');
360
    }
361
    
362
    /**
363
     * Check if the device is ready for a cover command
364
     *
365
     * @return boolean
366
     */
367
    public function isReadyForCommand()
368
    {
369
        return ($this->cover_status == 'open' || $this->cover_status == 'closed' || $this->cover_status == 'locked');
370
    }
371
    
372
    /**
373
     * Check if the current time is during the devices scheduled time to be open
374
     *
375
     * @return boolean
376
     */
377
    public function isDuringScheduleOpen()
378
    {
379
        $timezone = Auth::user()->timezone;
380
        //Get the open, close, and current time in the users timezone
381
        $open_time = new Carbon($this->open_time, $timezone);
382
        $close_time = new Carbon($this->close_time, $timezone);
383
        $time_now = Carbon::now($timezone);
384
    
385
        //Check if the current time is during the open schedule or not
386
        if ($time_now->gt($open_time) && $time_now->lt($close_time)) {
387
                    return true;
388
        } else {
389
                    return false;
390
        }
391
    }
392
    
393
    /**
394
     * Get the covers actual status based on the current command and the devices status
395
     *
396
     * @return string
397
     */
398
    public function actualCoverStatus()
399
    {
400
        $isOpen = $this->cover_status === 'open';
401
        $isClosed = $this->cover_status === 'closed';
402
        $isLocked = $this->cover_status === 'locked';
403
            
404
        switch ($this[ 'cover_command' ])
405
        {
406
            case 'open':
407
                if ($isOpen) {
408
                                    $status = 'open';
409
                } else if ($isLocked) {
410
                                    $status = 'unlocking';
411
                } else {
412
                                    $status = 'opening';
413
                }
414
                break;
415
            case 'close':
416
                if ($isClosed) {
417
                                    $status = 'closed';
418
                } else if ($isLocked) {
419
                                    $status = 'unlocking';
420
                } else {
421
                                    $status = 'closing';
422
                }
423
                break;
424
            case 'lock':
425
                $status = 'locked';
426
                break;
427
            default:
428
                $status = 'error';
429
        }
430
    
431
        if ($this->cover_status === 'error') {
432
                    $status = 'error';
433
        }
434
        
435
        return $status;
436
    }
437
    
438
    /**
439
     * Get the page number of the device for the dashboard device table pagination
440
     *
441
     * @param int $limit
442
     * @return double
443
     */
444
    public function dashPageNum($limit)
445
    {
446
        $pos = Device::where('location_id', '=', $this->location_id)
447
            ->where('name', '<=', $this->name)
448
            ->orderBy('name', 'ASC')
449
            ->count();
450
        
451
        return ceil($pos / $limit);
452
    }
453
}
454