14 Commits

  1. 2
      .env.example
  2. 45
      app/Channels/DBChannel.php
  3. 50
      app/Channels/Messages/SocketMessage.php
  4. 66
      app/Channels/SocketChannel.php
  5. 16
      app/Http/Controllers/AuthController.php
  6. 23
      app/Http/Controllers/NotificationController.php
  7. 5
      app/Listeners/BusinessUserCreateNotif.php
  8. 2
      app/Listeners/ProjectUserCreateNotif.php
  9. 14
      app/Models/User.php
  10. 18
      app/Notifications/DBNotification.php
  11. 3
      app/Notifications/FcmNotification.php
  12. 63
      app/Notifications/SmsNotification.php
  13. 52
      app/Notifications/SocketNotification.php
  14. 8
      app/Providers/AppServiceProvider.php
  15. 19
      app/Utilities/HelperClass/NotificationHelper.php
  16. 3
      composer.json
  17. 299
      composer.lock
  18. 63
      config/logging.php
  19. 18
      config/socket.php
  20. 1
      database/migrations/2021_03_08_114700_create_notifications_table.php
  21. 40
      docker-compose.yml
  22. 1990
      liwo.json
  23. 13
      routes/api.php

2
.env.example

@ -7,7 +7,7 @@ APP_DEBUG=true
APP_URL=http://localhost
APP_TIMEZONE="Asia/Tehran"
LOG_CHANNEL=stack
LOG_CHANNEL=gelf
LOG_LEVEL=debug
DB_CONNECTION=mysql

45
app/Channels/DBChannel.php

@ -0,0 +1,45 @@
<?php
namespace App\Channels;
use Illuminate\Notifications\Channels\DatabaseChannel;
use Illuminate\Notifications\Notification;
class DBChannel extends DatabaseChannel
{
/**
* Get the data for the notification.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return array
*
* @throws \RuntimeException
*/
protected function getOptionalData($notifiable, Notification $notification)
{
if (method_exists($notification, 'toDatabaseOptional')) {
return is_array($data = $notification->toDatabaseOptional($notifiable))
? $data : [$data];
}
}
/**
* Build an array payload for the DatabaseNotification Model.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return array
*/
protected function buildPayload($notifiable, Notification $notification)
{
return [
'id' => $notification->id,
'type' => get_class($notification),
'data' => $this->getData($notifiable, $notification),
'read_at' => null,
] + $this->getOptionalData($notifiable, $notification);
}
}

50
app/Channels/Messages/SocketMessage.php

@ -0,0 +1,50 @@
<?php
namespace App\Channels\Messages;
class SocketMessage
{
/**
* The devices token to send the message from.
*
* @var array|string
*/
public $to;
/**
* The data of the Socket message.
*
* @var array
*/
public $data;
/**
* Set the devices token to send the message from.
*
* @param array|string $to
* @return $this
*/
public function to($to)
{
$this->to = $to;
return $this;
}
/**
* Set the data of the socket message.
*
* @param array $data
* @return $this
*/
public function data(array $data)
{
$this->data = $data;
return $this;
}
}

66
app/Channels/SocketChannel.php

@ -0,0 +1,66 @@
<?php
namespace App\Channels;
use Illuminate\Notifications\Notification;
use GuzzleHttp\Client as HttpClient;
class SocketChannel
{
/**
* The API URL for Socket.
*
* @var string
*/
protected $socket_url;
/**
* The HTTP client instance.
*
* @var \GuzzleHttp\Client
*/
protected $http;
/**
* Create a new Socket channel instance.
*
* @param \GuzzleHttp\Client $http
* @return void
*/
public function __construct(HttpClient $http, string $socket_url)
{
$this->http = $http;
$this->socket_url = $socket_url;
}
/**
* Send the given notification.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return void
*/
public function send($notifiable, Notification $notification)
{
$message = $notification->toSocket($notifiable);
$message->to($notifiable->routeNotificationFor('socket', $notification));
if (! $message->to) {
return;
}
try {
$this->http->post($this->socket_url . '/emit/' . $message->to, [
'headers' => [
'Content-Type' => 'application/json',
],
'json' => ['data' => $message->data],
]);
} catch (\GuzzleHttp\Exception\ConnectException $e) {
report($e);
}
}
}

16
app/Http/Controllers/AuthController.php

@ -249,6 +249,22 @@ class AuthController extends Controller
return 'success';
}
public function updateFcmToken(Request $request)
{
Auth::user()->fingerprints()->where(
[
['agent', request()->getAgent()],
['ip', request()->getClientIp()],
['os', request()->getOS()],
['latitude', \request()->getLocation()->getAttribute('lat')],
['longitude', \request()->getLocation()->getAttribute('lon')],
]
)->firstOrFail()->update([
'fcm_token' => $request->fcm_token
]);
return $this->authWithInfo();
}
public function createFingerPrint()
{
$attributes = [

23
app/Http/Controllers/NotificationController.php

@ -0,0 +1,23 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class NotificationController extends Controller
{
public function index($business)
{
return Auth::user()->notifications()
->where('data->business_id', $business)->get();
}
public function markAsRead($business, $notification)
{
return Auth::user()->unreadNotifications()
->where('business_id', $business)
->findOrFail($notification)
->markAsRead();
}
}

5
app/Listeners/BusinessUserCreateNotif.php

@ -36,11 +36,12 @@ class BusinessUserCreateNotif
$payload = $event->message;
if ($payload->data->original->level === enum('levels.inactive.id')) {
// When user level in business is zero, probably user added to business by system
// And not necessary send notification to stockholders
// And not necessary send notification to stakeholders
return;
}
$new_user = User::findOrFail($payload->data->original->user_id);
$owners = Business::findOrFail($payload->business)->owners()->where('id', '!=', $new_user->id)->get();
$owners = Business::findOrFail($payload->business)->owners()
->whereNotIn('id', [$new_user->id, auth()->id()])->get();
$users = $owners->prepend($new_user);

2
app/Listeners/ProjectUserCreateNotif.php

@ -37,7 +37,7 @@ class ProjectUserCreateNotif
$new_user = User::findOrFail($payload->data->original->user_id);
$project = Project::findOrFail($payload->data->original->project_id);
$owners_id = request('_business_info')['info']['projects'][$project->id]['members']->reject(function ($item, $key) use ($new_user) {
return $item['level'] < enum('levels.owner.id') || $key === $new_user->id;
return $item['level'] < enum('levels.owner.id') || $key === $new_user->id || $key === auth()->id();
})->toArray();
$owners = User::whereIn('id', array_keys($owners_id))->get();

14
app/Models/User.php

@ -2,10 +2,6 @@
namespace App\Models;
use App\Models\File;
use App\Models\Model;
use App\Models\SoftDeletes;
use App\Models\ReportableRelation;
use Illuminate\Notifications\Notifiable;
use Illuminate\Validation\Rule;
use Illuminate\Http\UploadedFile;
@ -54,6 +50,16 @@ class User extends Model implements AuthenticatableContract, AuthorizableContrac
return $this->fingerprints->whereNotNull('fcm_token')->pluck('fcm_token')->all();
}
/**
* Specifies the user's Socket room
*
* @return string
*/
public function routeNotificationForSocket()
{
return request('_business_info')['id'] ?? null;
}
public function updateRelations()
{
// projects relations

18
app/Notifications/DBNotification.php

@ -3,8 +3,6 @@
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class DBNotification extends Notification
@ -31,7 +29,7 @@ class DBNotification extends Notification
*/
public function via($notifiable)
{
return ['database'];
return ['db'];
}
/**
@ -43,7 +41,19 @@ class DBNotification extends Notification
public function toArray($notifiable)
{
return [
'data' => $this->message['body']
'data' => $this->message['body'],
];
}
/**
* Get the array for optional database field that added to original table.
* @param $notifiable
* @return array
*/
public function toDatabaseOptional($notifiable)
{
return [
'business_id' => $this->message['business_id'] ?? null
];
}
}

3
app/Notifications/FcmNotification.php

@ -34,7 +34,7 @@ class FcmNotification extends Notification
}
/**
* Get the voice representation of the notification.
* Get the fcm representation of the notification.
*
* @param mixed $notifiable
* @return FcmMessage
@ -45,6 +45,7 @@ class FcmNotification extends Notification
->data([
'title' => $this->message['title'],
'body' => $this->message['body'],
'openURL' => "https://facebook.com/"
]);
}

63
app/Notifications/SmsNotification.php

@ -0,0 +1,63 @@
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class SmsNotification extends Notification
{
use Queueable;
public $message;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct($message)
{
$this->message = $message;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* @param mixed $notifiable
* @return array
*/
public function toArray($notifiable)
{
return [
//
];
}
}

52
app/Notifications/SocketNotification.php

@ -0,0 +1,52 @@
<?php
namespace App\Notifications;
use App\Channels\Messages\SocketMessage;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class SocketNotification extends Notification
{
use Queueable;
public $message;
/**
* Create a new notification instance.
*
* @return void
*/
public function __construct($message)
{
$this->message = $message;
}
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['socket'];
}
/**
* Get the socket representation of the notification.
*
* @param mixed $notifiable
* @return SocketMessage
*/
public function toSocket($notifiable)
{
return (new SocketMessage())
->data([
'title' => $this->message['title'],
'body' => $this->message['body'],
]);
}
}

8
app/Providers/AppServiceProvider.php

@ -2,7 +2,9 @@
namespace App\Providers;
use App\Channels\DBChannel;
use App\Channels\FcmChannel;
use App\Channels\SocketChannel;
use Illuminate\Notifications\ChannelManager;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\ServiceProvider;
@ -21,6 +23,12 @@ class AppServiceProvider extends ServiceProvider
$service->extend('fcm', function ($app) {
return new FcmChannel(new HttpClient, config('fcm.key'));
});
$service->extend('socket', function ($app) {
return new SocketChannel(new HttpClient, config('socket.url'));
});
$service->extend('db', function ($app) {
return new DBChannel();
});
});
}

19
app/Utilities/HelperClass/NotificationHelper.php

@ -7,6 +7,7 @@ namespace App\Utilities\HelperClass;
use App\Notifications\DBNotification;
use App\Notifications\FcmNotification;
use App\Notifications\MailNotification;
use App\Notifications\SocketNotification;
use Illuminate\Support\Facades\Notification;
class NotificationHelper
@ -26,7 +27,8 @@ class NotificationHelper
'greeting' => $this->getMessageLine($payload, $route.'greeting'),
'subject' => $this->getMessageLine($payload, $route.'subject'),
'title' => $this->getMessageLine($payload, $route.'title'),
'body' => $this->getMessageLine($payload, $route.'body', $options)
'body' => $this->getMessageLine($payload, $route.'body', $options),
'business_id' => request('_business_info')['id']
];
return $this;
}
@ -56,20 +58,17 @@ class NotificationHelper
case "emergency":
// Notification::send($users, new SmsNotification($notif));
case "critical":
Notification::send($users, new MailNotification($notif));
Notification::send($users, new MailNotification($this->notif));
case "high":
Notification::send($users, new DBNotification($notif));
Notification::send($users, new DBNotification($this->notif));
case "medium":
Notification::send($users, new FcmNotification($notif));
Notification::send($users, new FcmNotification($this->notif));
case "low":
// Notification::send($users, new SocketNotification($notif));
Notification::send($users, new SocketNotification($this->notif));
break;
default:
// Notification::send($users, new SocketNotification($notif));
Notification::send($users, new SocketNotification($this->notif));
}
// Notification::send($users, new MailNotification($this->notif));
// Notification::send($users, new DBNotification($this->notif));
// Notification::send($users, new FcmNotification($this->notif));
}
}

3
composer.json

@ -25,7 +25,8 @@
"spatie/image": "^1.0",
"spatie/laravel-medialibrary": "^9.0",
"spatie/laravel-query-builder": "^3.3",
"torann/geoip": "^3.0"
"torann/geoip": "^3.0",
"hedii/laravel-gelf-logger": "^6.0"
},
"require-dev": {
"facade/ignition": "^2.5",

299
composer.lock

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5bd413ba3541289df0ed987c8c36efb7",
"content-hash": "ad69869827abcf682bf25c0728bb8eed",
"packages": [
{
"name": "anik/amqp",
@ -63,16 +63,16 @@
},
{
"name": "asm89/stack-cors",
"version": "v2.0.2",
"version": "v2.0.3",
"source": {
"type": "git",
"url": "https://github.com/asm89/stack-cors.git",
"reference": "8d8f88b3b3830916be94292c1fbce84433efb1aa"
"reference": "9cb795bf30988e8c96dd3c40623c48a877bc6714"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/asm89/stack-cors/zipball/8d8f88b3b3830916be94292c1fbce84433efb1aa",
"reference": "8d8f88b3b3830916be94292c1fbce84433efb1aa",
"url": "https://api.github.com/repos/asm89/stack-cors/zipball/9cb795bf30988e8c96dd3c40623c48a877bc6714",
"reference": "9cb795bf30988e8c96dd3c40623c48a877bc6714",
"shasum": ""
},
"require": {
@ -113,22 +113,22 @@
],
"support": {
"issues": "https://github.com/asm89/stack-cors/issues",
"source": "https://github.com/asm89/stack-cors/tree/v2.0.2"
"source": "https://github.com/asm89/stack-cors/tree/v2.0.3"
},
"time": "2020-10-29T16:03:21+00:00"
"time": "2021-03-11T06:42:03+00:00"
},
{
"name": "aws/aws-sdk-php",
"version": "3.173.25",
"version": "3.173.28",
"source": {
"type": "git",
"url": "https://github.com/aws/aws-sdk-php.git",
"reference": "69e4653acf8cd855e9010ec4e0e0a7d074c77ee1"
"reference": "593baa5930896bb443c437032daf4016e1e3878d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/69e4653acf8cd855e9010ec4e0e0a7d074c77ee1",
"reference": "69e4653acf8cd855e9010ec4e0e0a7d074c77ee1",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/593baa5930896bb443c437032daf4016e1e3878d",
"reference": "593baa5930896bb443c437032daf4016e1e3878d",
"shasum": ""
},
"require": {
@ -203,9 +203,9 @@
"support": {
"forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
"issues": "https://github.com/aws/aws-sdk-php/issues",
"source": "https://github.com/aws/aws-sdk-php/tree/3.173.25"
"source": "https://github.com/aws/aws-sdk-php/tree/3.173.28"
},
"time": "2021-03-09T19:14:56+00:00"
"time": "2021-03-12T19:29:55+00:00"
},
{
"name": "beberlei/assert",
@ -870,6 +870,64 @@
],
"time": "2020-04-13T13:17:36+00:00"
},
{
"name": "graylog2/gelf-php",
"version": "1.7.0",
"source": {
"type": "git",
"url": "https://github.com/bzikarsky/gelf-php.git",
"reference": "16cab667fa01e6e298af1ec3279fe08d43e40a96"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bzikarsky/gelf-php/zipball/16cab667fa01e6e298af1ec3279fe08d43e40a96",
"reference": "16cab667fa01e6e298af1ec3279fe08d43e40a96",
"shasum": ""
},
"require": {
"paragonie/constant_time_encoding": "^1|^2",
"php": ">=5.6",
"psr/log": "~1.0"
},
"provide": {
"psr/log-implementation": "~1.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7|^6.5|^7.5",
"squizlabs/php_codesniffer": "^3.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4.x-dev"
}
},
"autoload": {
"psr-4": {
"Gelf\\": "src/Gelf"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Benjamin Zikarsky",
"email": "benjamin@zikarsky.de"
},
{
"name": "gelf-php contributors",
"homepage": "https://github.com/bzikarsky/gelf-php/contributors"
}
],
"description": "A php implementation to send log-messages to a GELF compatible backend like Graylog2.",
"support": {
"issues": "https://github.com/bzikarsky/gelf-php/issues",
"source": "https://github.com/bzikarsky/gelf-php/tree/1.7.0"
},
"time": "2021-02-04T09:05:55+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "7.2.0",
@ -1102,6 +1160,63 @@
},
"time": "2020-09-30T07:37:11+00:00"
},
{
"name": "hedii/laravel-gelf-logger",
"version": "6.0.0",
"source": {
"type": "git",
"url": "https://github.com/hedii/laravel-gelf-logger.git",
"reference": "231f6dfc41546bfe5e1e02bc85f98d0d5db811c1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/hedii/laravel-gelf-logger/zipball/231f6dfc41546bfe5e1e02bc85f98d0d5db811c1",
"reference": "231f6dfc41546bfe5e1e02bc85f98d0d5db811c1",
"shasum": ""
},
"require": {
"graylog2/gelf-php": "^1.6",
"illuminate/log": "^8.12",
"php": "^7.3|^8.0"
},
"require-dev": {
"orchestra/testbench": "^6.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Hedii\\LaravelGelfLogger\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "hedii",
"homepage": "https://hedichaibi.com"
}
],
"description": "A Laravel package to send logs to a gelf compatible backend like graylog",
"keywords": [
"gelf",
"graylog",
"graylog2",
"hedii",
"laravel",
"laravel-gelf",
"log",
"logging",
"php",
"udp"
],
"support": {
"issues": "https://github.com/hedii/laravel-gelf-logger/issues",
"source": "https://github.com/hedii/laravel-gelf-logger"
},
"time": "2020-11-30T09:39:06+00:00"
},
{
"name": "intervention/image",
"version": "2.5.1",
@ -2845,6 +2960,73 @@
},
"time": "2020-11-07T02:01:34+00:00"
},
{
"name": "paragonie/constant_time_encoding",
"version": "v2.4.0",
"source": {
"type": "git",
"url": "https://github.com/paragonie/constant_time_encoding.git",
"reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c",
"reference": "f34c2b11eb9d2c9318e13540a1dbc2a3afbd939c",
"shasum": ""
},
"require": {
"php": "^7|^8"
},
"require-dev": {
"phpunit/phpunit": "^6|^7|^8|^9",
"vimeo/psalm": "^1|^2|^3|^4"
},
"type": "library",
"autoload": {
"psr-4": {
"ParagonIE\\ConstantTime\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Paragon Initiative Enterprises",
"email": "security@paragonie.com",
"homepage": "https://paragonie.com",
"role": "Maintainer"
},
{
"name": "Steve 'Sc00bz' Thomas",
"email": "steve@tobtu.com",
"homepage": "https://www.tobtu.com",
"role": "Original Developer"
}
],
"description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
"keywords": [
"base16",
"base32",
"base32_decode",
"base32_encode",
"base64",
"base64_decode",
"base64_encode",
"bin2hex",
"encoding",
"hex",
"hex2bin",
"rfc4648"
],
"support": {
"email": "info@paragonie.com",
"issues": "https://github.com/paragonie/constant_time_encoding/issues",
"source": "https://github.com/paragonie/constant_time_encoding"
},
"time": "2020-12-06T15:14:20+00:00"
},
{
"name": "php-amqplib/php-amqplib",
"version": "v2.12.1",
@ -3459,16 +3641,16 @@
},
{
"name": "psy/psysh",
"version": "v0.10.6",
"version": "v0.10.7",
"source": {
"type": "git",
"url": "https://github.com/bobthecow/psysh.git",
"reference": "6f990c19f91729de8b31e639d6e204ea59f19cf3"
"reference": "a395af46999a12006213c0c8346c9445eb31640c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/6f990c19f91729de8b31e639d6e204ea59f19cf3",
"reference": "6f990c19f91729de8b31e639d6e204ea59f19cf3",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/a395af46999a12006213c0c8346c9445eb31640c",
"reference": "a395af46999a12006213c0c8346c9445eb31640c",
"shasum": ""
},
"require": {
@ -3529,9 +3711,9 @@
],
"support": {
"issues": "https://github.com/bobthecow/psysh/issues",
"source": "https://github.com/bobthecow/psysh/tree/v0.10.6"
"source": "https://github.com/bobthecow/psysh/tree/v0.10.7"
},
"time": "2021-01-18T15:53:43+00:00"
"time": "2021-03-14T02:14:56+00:00"
},
{
"name": "ralouphie/getallheaders",
@ -3748,20 +3930,21 @@
},
{
"name": "spatie/image",
"version": "1.10.2",
"version": "1.10.4",
"source": {
"type": "git",
"url": "https://github.com/spatie/image.git",
"reference": "12662673fbe649bffcd3a24188a404dc31fa118c"
"reference": "7ea129bc7b7521864c5a540e3b1c14ea194316d3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/spatie/image/zipball/12662673fbe649bffcd3a24188a404dc31fa118c",
"reference": "12662673fbe649bffcd3a24188a404dc31fa118c",
"url": "https://api.github.com/repos/spatie/image/zipball/7ea129bc7b7521864c5a540e3b1c14ea194316d3",
"reference": "7ea129bc7b7521864c5a540e3b1c14ea194316d3",
"shasum": ""
},
"require": {
"ext-exif": "*",
"ext-json": "*",
"ext-mbstring": "*",
"league/glide": "^1.6",
"php": "^7.2|^8.0",
@ -3771,7 +3954,8 @@
},
"require-dev": {
"phpunit/phpunit": "^8.0|^9.0",
"symfony/var-dumper": "^4.0|^5.0"
"symfony/var-dumper": "^4.0|^5.0",
"vimeo/psalm": "^4.6"
},
"type": "library",
"autoload": {
@ -3799,7 +3983,7 @@
],
"support": {
"issues": "https://github.com/spatie/image/issues",
"source": "https://github.com/spatie/image/tree/1.10.2"
"source": "https://github.com/spatie/image/tree/1.10.4"
},
"funding": [
{
@ -3811,7 +3995,7 @@
"type": "github"
}
],
"time": "2021-01-26T07:53:19+00:00"
"time": "2021-03-10T16:11:40+00:00"
},
{
"name": "spatie/image-optimizer",
@ -4169,16 +4353,16 @@
},
{
"name": "symfony/console",
"version": "v5.2.4",
"version": "v5.2.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "d6d0cc30d8c0fda4e7b213c20509b0159a8f4556"
"reference": "938ebbadae1b0a9c9d1ec313f87f9708609f1b79"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/d6d0cc30d8c0fda4e7b213c20509b0159a8f4556",
"reference": "d6d0cc30d8c0fda4e7b213c20509b0159a8f4556",
"url": "https://api.github.com/repos/symfony/console/zipball/938ebbadae1b0a9c9d1ec313f87f9708609f1b79",
"reference": "938ebbadae1b0a9c9d1ec313f87f9708609f1b79",
"shasum": ""
},
"require": {
@ -4246,7 +4430,7 @@
"terminal"
],
"support": {
"source": "https://github.com/symfony/console/tree/v5.2.4"
"source": "https://github.com/symfony/console/tree/v5.2.5"
},
"funding": [
{
@ -4262,7 +4446,7 @@
"type": "tidelift"
}
],
"time": "2021-02-23T10:08:49+00:00"
"time": "2021-03-06T13:42:15+00:00"
},
{
"name": "symfony/css-selector",
@ -4844,16 +5028,16 @@
},
{
"name": "symfony/http-kernel",
"version": "v5.2.4",
"version": "v5.2.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
"reference": "c452dbe4f385f030c3957821bf921b13815d6140"
"reference": "b8c63ef63c2364e174c3b3e0ba0bf83455f97f73"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/c452dbe4f385f030c3957821bf921b13815d6140",
"reference": "c452dbe4f385f030c3957821bf921b13815d6140",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/b8c63ef63c2364e174c3b3e0ba0bf83455f97f73",
"reference": "b8c63ef63c2364e174c3b3e0ba0bf83455f97f73",
"shasum": ""
},
"require": {
@ -4936,7 +5120,7 @@
"description": "Provides a structured process for converting a Request into a Response",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/http-kernel/tree/v5.2.4"
"source": "https://github.com/symfony/http-kernel/tree/v5.2.5"
},
"funding": [
{
@ -4952,20 +5136,20 @@
"type": "tidelift"
}
],
"time": "2021-03-04T18:05:55+00:00"
"time": "2021-03-10T17:07:35+00:00"
},
{
"name": "symfony/mime",
"version": "v5.2.4",
"version": "v5.2.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/mime.git",
"reference": "5155d2fe14ef1eb150e3bdbbc1ec1455df95e9cd"
"reference": "554ba128f1955038b45db5e1fa7e93bfc683b139"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/5155d2fe14ef1eb150e3bdbbc1ec1455df95e9cd",
"reference": "5155d2fe14ef1eb150e3bdbbc1ec1455df95e9cd",
"url": "https://api.github.com/repos/symfony/mime/zipball/554ba128f1955038b45db5e1fa7e93bfc683b139",
"reference": "554ba128f1955038b45db5e1fa7e93bfc683b139",
"shasum": ""
},
"require": {
@ -4976,12 +5160,13 @@
"symfony/polyfill-php80": "^1.15"
},
"conflict": {
"egulias/email-validator": "~3.0.0",
"phpdocumentor/reflection-docblock": "<3.2.2",
"phpdocumentor/type-resolver": "<1.4.0",
"symfony/mailer": "<4.4"
},
"require-dev": {
"egulias/email-validator": "^2.1.10",
"egulias/email-validator": "^2.1.10|^3.1",
"phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0",
"symfony/dependency-injection": "^4.4|^5.0",
"symfony/property-access": "^4.4|^5.1",
@ -5018,7 +5203,7 @@
"mime-type"
],
"support": {
"source": "https://github.com/symfony/mime/tree/v5.2.4"
"source": "https://github.com/symfony/mime/tree/v5.2.5"
},
"funding": [
{
@ -5034,7 +5219,7 @@
"type": "tidelift"
}
],
"time": "2021-02-15T18:55:04+00:00"
"time": "2021-03-07T16:08:20+00:00"
},
{
"name": "symfony/polyfill-ctype",
@ -6081,16 +6266,16 @@
},
{
"name": "symfony/translation",
"version": "v5.2.4",
"version": "v5.2.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "74b0353ab34ff4cca827a2cf909e325d96815e60"
"reference": "0947ab1e3aabd22a6bef393874b2555d2bb976da"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/74b0353ab34ff4cca827a2cf909e325d96815e60",
"reference": "74b0353ab34ff4cca827a2cf909e325d96815e60",
"url": "https://api.github.com/repos/symfony/translation/zipball/0947ab1e3aabd22a6bef393874b2555d2bb976da",
"reference": "0947ab1e3aabd22a6bef393874b2555d2bb976da",
"shasum": ""
},
"require": {
@ -6154,7 +6339,7 @@
"description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/translation/tree/v5.2.4"
"source": "https://github.com/symfony/translation/tree/v5.2.5"
},
"funding": [
{
@ -6170,7 +6355,7 @@
"type": "tidelift"
}
],
"time": "2021-03-04T15:41:09+00:00"
"time": "2021-03-06T07:59:01+00:00"
},
{
"name": "symfony/translation-contracts",
@ -6252,16 +6437,16 @@
},
{
"name": "symfony/var-dumper",
"version": "v5.2.4",
"version": "v5.2.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
"reference": "6a81fec0628c468cf6d5c87a4d003725e040e223"
"reference": "002ab5a36702adf0c9a11e6d8836623253e9045e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/6a81fec0628c468cf6d5c87a4d003725e040e223",
"reference": "6a81fec0628c468cf6d5c87a4d003725e040e223",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/002ab5a36702adf0c9a11e6d8836623253e9045e",
"reference": "002ab5a36702adf0c9a11e6d8836623253e9045e",
"shasum": ""
},
"require": {
@ -6320,7 +6505,7 @@
"dump"
],
"support": {
"source": "https://github.com/symfony/var-dumper/tree/v5.2.4"
"source": "https://github.com/symfony/var-dumper/tree/v5.2.5"
},
"funding": [
{
@ -6336,7 +6521,7 @@
"type": "tidelift"
}
],
"time": "2021-02-18T23:11:19+00:00"
"time": "2021-03-06T07:59:01+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",

63
config/logging.php

@ -40,5 +40,68 @@ return [
'level' => 'debug',
'days' => 14,
],
'gelf' => [
'driver' => 'custom',
'via' => \Hedii\LaravelGelfLogger\GelfLoggerFactory::class,
// This optional option determines the processors that should be
// pushed to the handler. This option is useful to modify a field
// in the log context (see NullStringProcessor), or to add extra
// data. Each processor must be a callable or an object with an
// __invoke method: see monolog documentation about processors.
// Default is an empty array.
'processors' => [
\Hedii\LaravelGelfLogger\Processors\NullStringProcessor::class,
// another processor...
],
// This optional option determines the minimum "level" a message
// must be in order to be logged by the channel. Default is 'debug'
'level' => 'debug',
// This optional option determines the channel name sent with the
// message in the 'facility' field. Default is equal to app.env
// configuration value
'name' => 'my-custom-name',
// This optional option determines the system name sent with the
// message in the 'source' field. When forgotten or set to null,
// the current hostname is used.
'system_name' => null,
// This optional option determines if you want the UDP, TCP or HTTP
// transport for the gelf log messages. Default is UDP
'transport' => 'udp',
// This optional option determines the host that will receive the
// gelf log messages. Default is 127.0.0.1
'host' => 'graylog',
// This optional option determines the port on which the gelf
// receiver host is listening. Default is 12201
'port' => 12201,
// This optional option determines the path used for the HTTP
// transport. When forgotten or set to null, default path '/gelf'
// is used.
'path' => null,
// This optional option determines the maximum length per message
// field. When forgotten or set to null, the default value of
// \Monolog\Formatter\GelfMessageFormatter::DEFAULT_MAX_LENGTH is
// used (currently this value is 32766)
'max_length' => null,
// This optional option determines the prefix for 'context' fields
// from the Monolog record. Default is null (no context prefix)
'context_prefix' => null,
// This optional option determines the prefix for 'extra' fields
// from the Monolog record. Default is null (no extra prefix)
'extra_prefix' => null,
],
],
];

18
config/socket.php

@ -0,0 +1,18 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| FCM API Key
|--------------------------------------------------------------------------
|
| This key allows you to send Push Notifications. To obtain this key go
| to the porject settings and click on the "Cloud Messaging" tab, now
| copy the API Key of "Legacy server key".
|
*/
'url' => env('SOCKET_URL'),
];

1
database/migrations/2021_03_08_114700_create_notifications_table.php

@ -17,6 +17,7 @@ class CreateNotificationsTable extends Migration
$table->uuid('id')->primary();
$table->string('type');
$table->morphs('notifiable');
$table->unsignedBigInteger('business_id');
$table->text('data');
$table->timestamp('read_at')->nullable();
$table->timestamps();

40
docker-compose.yml

@ -21,7 +21,7 @@ services:
image: minio/minio
command: server /data
ports:
- 9000:9000
- 9005:9000
environment:
MINIO_ACCESS_KEY: root
MINIO_SECRET_KEY: minioroot
@ -109,9 +109,47 @@ services:
- 8025:8025 # web ui
networks:
- hi-user
mongo:
container_name: "mongo"
image: mongo:latest
networks:
- hi-user
elasticsearch:
container_name: "elastic"
image: docker.elastic.co/elasticsearch/elasticsearch:7.11.2
environment:
- http.host=0.0.0.0
- transport.host=localhost
- network.host=0.0.0.0
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
ulimits:
memlock:
soft: 512
hard: 1024
networks:
- hi-user
graylog:
container_name: "graylog"
image: graylog/graylog:4.0.5
environment:
GRAYLOG_HTTP_EXTERNAL_URI: "http://127.0.0.1:9000/"
GRAYLOG_PASSWORD_SECRET: supersecretpassword
GRAYLOG_ROOT_PASSWORD_SHA2: "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918"
GRAYLOG_ELASTICSEARCH_VERSION: 7
restart: always
depends_on:
- mongo
- elasticsearch
ports:
- 9000:9000
- 12201:12201
- 1514:1514
networks:
- hi-user
networks:
hi-user:
external: false
driver: bridge
hi:
external: true
volumes:

1990
liwo.json
File diff suppressed because it is too large
View File

13
routes/api.php

@ -2,6 +2,14 @@
/** @var \Illuminate\Routing\$router */
$router->get('/lab', function () {
throw new \Exception("^_^");
});
$router->get('/ntest', function () {
$user = \App\Models\User::find(1);
\Illuminate\Support\Facades\Notification::send($user, new \App\Notifications\SocketNotification(['title' => "hello!!!", 'body' => 'sss']));
})->middleware('bindBusiness');
$router->group(['prefix' => 'actions'], function () use ($router) {
$router->group(['prefix' => 'businesses'], function () use ($router) {
$router->group(['prefix' => '{business}', 'middleware' => 'bindBusiness'], function () use ($router) {
@ -29,6 +37,8 @@ $router->group(['prefix' => 'auth'], function () use ($router) {
$router->get('google/redirect', 'AuthController@redirectToGoogle')->name('google.redirect');
$router->get('google/callback', 'AuthController@handleGoogleCallback')->name('google.callback');
$router->get('update-fcm', 'AuthController@updateFcmToken')->middleware('auth:api');
});
$router->group(['prefix' => 'businesses', 'middleware' => 'auth:api'], function () use ($router) {
@ -37,6 +47,9 @@ $router->group(['prefix' => 'businesses', 'middleware' => 'auth:api'], function
$router->group(['prefix' => '{business}', 'middleware' => 'bindBusiness'], function () use ($router) {
$router->get('/notifications', 'NotificationController@index');
$router->get('/notifications/{notification}/read', 'NotificationController@markAsRead');
$router->get('/tasks', 'TaskController@index');
$router->get('/works', 'WorkController@index');
$router->get('statistics', 'StatisticController@index');

Loading…
Cancel
Save