├── posts-microservice ├── public │ ├── favicon.ico │ ├── robots.txt │ ├── .htaccess │ └── index.php ├── resources │ ├── css │ │ └── app.css │ └── js │ │ ├── app.js │ │ └── bootstrap.js ├── database │ ├── .gitignore │ ├── seeders │ │ └── DatabaseSeeder.php │ ├── migrations │ │ ├── 2022_05_08_124254_create_posts_table.php │ │ ├── 2019_08_19_000000_create_failed_jobs_table.php │ │ └── 2022_05_11_071936_create_job_batches_table.php │ └── factories │ │ └── UserFactory.php ├── bootstrap │ ├── cache │ │ └── .gitignore │ └── app.php ├── storage │ ├── logs │ │ └── .gitignore │ ├── app │ │ ├── public │ │ │ └── .gitignore │ │ └── .gitignore │ └── framework │ │ ├── sessions │ │ └── .gitignore │ │ ├── testing │ │ └── .gitignore │ │ ├── views │ │ └── .gitignore │ │ ├── cache │ │ ├── data │ │ │ └── .gitignore │ │ └── .gitignore │ │ └── .gitignore ├── img.png ├── img_1.png ├── img_2.png ├── img_3.png ├── img_4.png ├── img_5.png ├── config │ ├── microservices.php │ ├── cors.php │ ├── services.php │ ├── view.php │ ├── hashing.php │ ├── broadcasting.php │ └── sanctum.php ├── .gitattributes ├── tests │ ├── TestCase.php │ ├── Unit │ │ └── ExampleTest.php │ ├── Feature │ │ └── ExampleTest.php │ └── CreatesApplication.php ├── .styleci.yml ├── .gitignore ├── app │ ├── Http │ │ ├── Controllers │ │ │ ├── Api │ │ │ │ ├── Api Test.http │ │ │ │ ├── AuthController.php │ │ │ │ └── PostController.php │ │ │ └── Controller.php │ │ ├── Middleware │ │ │ ├── EncryptCookies.php │ │ │ ├── VerifyCsrfToken.php │ │ │ ├── PreventRequestsDuringMaintenance.php │ │ │ ├── TrustHosts.php │ │ │ ├── TrimStrings.php │ │ │ ├── Authenticate.php │ │ │ ├── TrustProxies.php │ │ │ ├── AuthenticateUserMiddleware.php │ │ │ └── RedirectIfAuthenticated.php │ │ ├── Resources │ │ │ └── PostResource.php │ │ └── Requests │ │ │ ├── Post │ │ │ └── CreatePostRequest.php │ │ │ └── Auth │ │ │ └── RegisterRequest.php │ ├── Models │ │ └── Post.php │ ├── Providers │ │ ├── BroadcastServiceProvider.php │ │ ├── AuthServiceProvider.php │ │ ├── EventServiceProvider.php │ │ ├── AppServiceProvider.php │ │ └── RouteServiceProvider.php │ ├── Console │ │ ├── Kernel.php │ │ └── Commands │ │ │ └── AutoImportPost.php │ ├── Jobs │ │ ├── ImportNextExecutionJob.php │ │ └── AutoImportPostJob.php │ ├── Traits │ │ └── HasUuid.php │ ├── Exceptions │ │ └── Handler.php │ └── Services │ │ └── PostService.php ├── .editorconfig ├── package.json ├── routes │ ├── web.php │ ├── channels.php │ ├── console.php │ └── api.php ├── lang │ └── en │ │ ├── pagination.php │ │ ├── auth.php │ │ └── passwords.php ├── webpack.mix.js ├── Dockerfile ├── .env.example ├── phpunit.xml ├── README.md ├── docker-compose.yml ├── artisan └── composer.json ├── users-microservice ├── public │ ├── favicon.ico │ ├── robots.txt │ ├── .htaccess │ └── index.php ├── resources │ ├── css │ │ └── app.css │ └── js │ │ ├── app.js │ │ └── bootstrap.js ├── database │ ├── .gitignore │ ├── seeders │ │ └── DatabaseSeeder.php │ ├── migrations │ │ ├── 2019_08_19_000000_create_failed_jobs_table.php │ │ ├── 2014_10_12_000000_create_users_table.php │ │ └── 2019_12_14_000001_create_personal_access_tokens_table.php │ └── factories │ │ └── UserFactory.php ├── bootstrap │ ├── cache │ │ └── .gitignore │ └── app.php ├── storage │ ├── logs │ │ └── .gitignore │ ├── app │ │ ├── public │ │ │ └── .gitignore │ │ └── .gitignore │ └── framework │ │ ├── sessions │ │ └── .gitignore │ │ ├── testing │ │ └── .gitignore │ │ ├── views │ │ └── .gitignore │ │ ├── cache │ │ ├── data │ │ │ └── .gitignore │ │ └── .gitignore │ │ └── .gitignore ├── routes │ ├── Auth Api Tests.http │ ├── web.php │ ├── channels.php │ ├── console.php │ └── api.php ├── .gitattributes ├── tests │ ├── TestCase.php │ ├── Unit │ │ └── ExampleTest.php │ ├── Feature │ │ └── ExampleTest.php │ └── CreatesApplication.php ├── .styleci.yml ├── app │ ├── Http │ │ ├── Controllers │ │ │ ├── Api │ │ │ │ ├── Api Test Endpoints.http │ │ │ │ ├── UserController.php │ │ │ │ └── AuthController.php │ │ │ └── Controller.php │ │ ├── Middleware │ │ │ ├── EncryptCookies.php │ │ │ ├── VerifyCsrfToken.php │ │ │ ├── PreventRequestsDuringMaintenance.php │ │ │ ├── TrustHosts.php │ │ │ ├── TrimStrings.php │ │ │ ├── Authenticate.php │ │ │ ├── TrustProxies.php │ │ │ └── RedirectIfAuthenticated.php │ │ └── Requests │ │ │ └── Auth │ │ │ └── RegisterRequest.php │ ├── Providers │ │ ├── BroadcastServiceProvider.php │ │ ├── AuthServiceProvider.php │ │ ├── EventServiceProvider.php │ │ ├── AppServiceProvider.php │ │ └── RouteServiceProvider.php │ ├── Console │ │ └── Kernel.php │ ├── Traits │ │ └── HasUuid.php │ ├── Exceptions │ │ └── Handler.php │ └── Models │ │ └── User.php ├── .gitignore ├── .editorconfig ├── package.json ├── lang │ └── en │ │ ├── pagination.php │ │ ├── auth.php │ │ └── passwords.php ├── webpack.mix.js ├── Dockerfile ├── README.md ├── config │ ├── cors.php │ ├── services.php │ ├── view.php │ ├── hashing.php │ ├── broadcasting.php │ └── sanctum.php ├── .env.example ├── docker-compose.yml ├── phpunit.xml ├── artisan └── composer.json ├── imports-microservice ├── public │ ├── favicon.ico │ ├── robots.txt │ ├── .htaccess │ └── index.php ├── resources │ ├── css │ │ └── app.css │ └── js │ │ ├── app.js │ │ └── bootstrap.js ├── database │ ├── .gitignore │ ├── seeders │ │ └── DatabaseSeeder.php │ └── migrations │ │ ├── 2022_05_08_151552_create_imports_table.php │ │ ├── 2019_08_19_000000_create_failed_jobs_table.php │ │ └── 2022_05_08_203035_create_job_batches_table.php ├── storage │ ├── logs │ │ └── .gitignore │ ├── app │ │ ├── public │ │ │ └── .gitignore │ │ └── .gitignore │ └── framework │ │ ├── views │ │ └── .gitignore │ │ ├── cache │ │ ├── data │ │ │ └── .gitignore │ │ └── .gitignore │ │ ├── sessions │ │ └── .gitignore │ │ ├── testing │ │ └── .gitignore │ │ └── .gitignore ├── bootstrap │ ├── cache │ │ └── .gitignore │ └── app.php ├── config │ ├── microservices.php │ ├── cors.php │ ├── services.php │ ├── view.php │ ├── hashing.php │ └── broadcasting.php ├── img.png ├── img_1.png ├── img_2.png ├── img_3.png ├── .gitattributes ├── tests │ ├── TestCase.php │ ├── Unit │ │ └── ExampleTest.php │ ├── Feature │ │ └── ExampleTest.php │ └── CreatesApplication.php ├── .styleci.yml ├── .gitignore ├── app │ ├── Models │ │ └── Import.php │ ├── Http │ │ ├── Middleware │ │ │ ├── EncryptCookies.php │ │ │ ├── VerifyCsrfToken.php │ │ │ ├── TrustHosts.php │ │ │ ├── PreventRequestsDuringMaintenance.php │ │ │ ├── TrimStrings.php │ │ │ ├── Authenticate.php │ │ │ ├── TrustProxies.php │ │ │ ├── AdminMiddleware.php │ │ │ └── RedirectIfAuthenticated.php │ │ ├── Controllers │ │ │ ├── Controller.php │ │ │ └── Api │ │ │ │ ├── AdminController.php │ │ │ │ └── AuthController.php │ │ └── Requests │ │ │ ├── Post │ │ │ └── ImportedPostRequest.php │ │ │ └── Auth │ │ │ └── RegisterRequest.php │ ├── Providers │ │ ├── BroadcastServiceProvider.php │ │ ├── AuthServiceProvider.php │ │ ├── EventServiceProvider.php │ │ ├── AppServiceProvider.php │ │ └── RouteServiceProvider.php │ ├── Jobs │ │ ├── TestJob.php │ │ ├── ImportNextExecutionJob.php │ │ └── AutoImportPostJob.php │ ├── Console │ │ └── Kernel.php │ ├── Traits │ │ └── HasUuid.php │ ├── Exceptions │ │ └── Handler.php │ └── Services │ │ ├── PostService.php │ │ └── ImportService.php ├── .editorconfig ├── package.json ├── routes │ ├── web.php │ ├── channels.php │ ├── api.php │ └── console.php ├── lang │ └── en │ │ ├── pagination.php │ │ ├── auth.php │ │ └── passwords.php ├── webpack.mix.js ├── Dockerfile ├── .env.example ├── phpunit.xml ├── README.md ├── docker-compose.yml ├── artisan └── composer.json ├── .DS_Store └── .idea ├── .gitignore ├── misc.xml ├── vcs.xml └── modules.xml /posts-microservice/public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /users-microservice/public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /imports-microservice/public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /imports-microservice/resources/css/app.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /posts-microservice/resources/css/app.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /users-microservice/resources/css/app.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /posts-microservice/database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite* 2 | -------------------------------------------------------------------------------- /users-microservice/database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite* 2 | -------------------------------------------------------------------------------- /imports-microservice/database/.gitignore: -------------------------------------------------------------------------------- 1 | *.sqlite* 2 | -------------------------------------------------------------------------------- /imports-microservice/resources/js/app.js: -------------------------------------------------------------------------------- 1 | require('./bootstrap'); 2 | -------------------------------------------------------------------------------- /imports-microservice/storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /posts-microservice/bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /posts-microservice/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /posts-microservice/resources/js/app.js: -------------------------------------------------------------------------------- 1 | require('./bootstrap'); 2 | -------------------------------------------------------------------------------- /posts-microservice/storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /users-microservice/bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /users-microservice/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /users-microservice/resources/js/app.js: -------------------------------------------------------------------------------- 1 | require('./bootstrap'); 2 | -------------------------------------------------------------------------------- /users-microservice/storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /imports-microservice/bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /imports-microservice/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /imports-microservice/storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /posts-microservice/storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /users-microservice/storage/app/public/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /imports-microservice/storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /imports-microservice/storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /posts-microservice/storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /posts-microservice/storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /posts-microservice/storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /posts-microservice/storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /users-microservice/storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !public/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /users-microservice/storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /users-microservice/storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /users-microservice/storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MusahMusah/blog-microservice/HEAD/.DS_Store -------------------------------------------------------------------------------- /imports-microservice/storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /imports-microservice/storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /imports-microservice/storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /posts-microservice/storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /users-microservice/storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /imports-microservice/storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /posts-microservice/storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /users-microservice/storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /imports-microservice/config/microservices.php: -------------------------------------------------------------------------------- 1 | env('USERS_MS') 5 | ]; 6 | -------------------------------------------------------------------------------- /posts-microservice/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MusahMusah/blog-microservice/HEAD/posts-microservice/img.png -------------------------------------------------------------------------------- /imports-microservice/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MusahMusah/blog-microservice/HEAD/imports-microservice/img.png -------------------------------------------------------------------------------- /posts-microservice/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MusahMusah/blog-microservice/HEAD/posts-microservice/img_1.png -------------------------------------------------------------------------------- /posts-microservice/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MusahMusah/blog-microservice/HEAD/posts-microservice/img_2.png -------------------------------------------------------------------------------- /posts-microservice/img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MusahMusah/blog-microservice/HEAD/posts-microservice/img_3.png -------------------------------------------------------------------------------- /posts-microservice/img_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MusahMusah/blog-microservice/HEAD/posts-microservice/img_4.png -------------------------------------------------------------------------------- /posts-microservice/img_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MusahMusah/blog-microservice/HEAD/posts-microservice/img_5.png -------------------------------------------------------------------------------- /imports-microservice/img_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MusahMusah/blog-microservice/HEAD/imports-microservice/img_1.png -------------------------------------------------------------------------------- /imports-microservice/img_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MusahMusah/blog-microservice/HEAD/imports-microservice/img_2.png -------------------------------------------------------------------------------- /imports-microservice/img_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MusahMusah/blog-microservice/HEAD/imports-microservice/img_3.png -------------------------------------------------------------------------------- /posts-microservice/config/microservices.php: -------------------------------------------------------------------------------- 1 | env('USERS_MS'), 5 | 'imports' => env('IMPORTS_MS', 'http://imports-microservice:8083'), 6 | ]; 7 | -------------------------------------------------------------------------------- /posts-microservice/storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | compiled.php 2 | config.php 3 | down 4 | events.scanned.php 5 | maintenance.php 6 | routes.php 7 | routes.scanned.php 8 | schedule-* 9 | services.json 10 | -------------------------------------------------------------------------------- /users-microservice/storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | compiled.php 2 | config.php 3 | down 4 | events.scanned.php 5 | maintenance.php 6 | routes.php 7 | routes.scanned.php 8 | schedule-* 9 | services.json 10 | -------------------------------------------------------------------------------- /imports-microservice/storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | compiled.php 2 | config.php 3 | down 4 | events.scanned.php 5 | maintenance.php 6 | routes.php 7 | routes.scanned.php 8 | schedule-* 9 | services.json 10 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /users-microservice/routes/Auth Api Tests.http: -------------------------------------------------------------------------------- 1 | POST http://localhost:8081/api/logout 2 | Content-Type: application/json 3 | Accept: application/json 4 | Authorization: Bearer 3|IRDSV3N6PE5ScPFpiVlzABEj5xNNhlCJhi1LdrDq 5 | 6 | -------------------------------------------------------------------------------- /imports-microservice/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | 3 | *.blade.php diff=html 4 | *.css diff=css 5 | *.html diff=html 6 | *.md diff=markdown 7 | *.php diff=php 8 | 9 | /.github export-ignore 10 | CHANGELOG.md export-ignore 11 | -------------------------------------------------------------------------------- /posts-microservice/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | 3 | *.blade.php diff=html 4 | *.css diff=css 5 | *.html diff=html 6 | *.md diff=markdown 7 | *.php diff=php 8 | 9 | /.github export-ignore 10 | CHANGELOG.md export-ignore 11 | -------------------------------------------------------------------------------- /users-microservice/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | 3 | *.blade.php diff=html 4 | *.css diff=css 5 | *.html diff=html 6 | *.md diff=markdown 7 | *.php diff=php 8 | 9 | /.github export-ignore 10 | CHANGELOG.md export-ignore 11 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | -------------------------------------------------------------------------------- /imports-microservice/tests/TestCase.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /posts-microservice/app/Http/Controllers/Api/Api Test.http: -------------------------------------------------------------------------------- 1 | POST http://localhost:8082/api/user/create-post 2 | Content-Type: application/json 3 | Accept: application/json 4 | Authorization: Coo 5 | 6 | 7 | { 8 | "title": "Post 1", 9 | "description": "Just a post", 10 | "publication_date": "2020-01-01:00:00" 11 | } 12 | -------------------------------------------------------------------------------- /imports-microservice/app/Models/Import.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /posts-microservice/tests/Unit/ExampleTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /users-microservice/tests/Unit/ExampleTest.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /posts-microservice/app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /users-microservice/app/Http/Middleware/EncryptCookies.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /posts-microservice/app/Http/Middleware/VerifyCsrfToken.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /posts-microservice/app/Models/Post.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Controllers/Controller.php: -------------------------------------------------------------------------------- 1 | create(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /imports-microservice/database/seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /posts-microservice/database/seeders/DatabaseSeeder.php: -------------------------------------------------------------------------------- 1 | create(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Middleware/TrustHosts.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function hosts() 15 | { 16 | return [ 17 | $this->allSubdomainsOfApplicationUrl(), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /posts-microservice/app/Http/Middleware/PreventRequestsDuringMaintenance.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /posts-microservice/app/Http/Middleware/TrustHosts.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function hosts() 15 | { 16 | return [ 17 | $this->allSubdomainsOfApplicationUrl(), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /users-microservice/app/Http/Middleware/PreventRequestsDuringMaintenance.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /users-microservice/app/Http/Middleware/TrustHosts.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | public function hosts() 15 | { 16 | return [ 17 | $this->allSubdomainsOfApplicationUrl(), 18 | ]; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Middleware/PreventRequestsDuringMaintenance.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | // 16 | ]; 17 | } 18 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | 'current_password', 16 | 'password', 17 | 'password_confirmation', 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /imports-microservice/tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 18 | 19 | $response->assertStatus(200); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /posts-microservice/app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | 'current_password', 16 | 'password', 17 | 'password_confirmation', 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /posts-microservice/tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 18 | 19 | $response->assertStatus(200); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /users-microservice/app/Http/Middleware/TrimStrings.php: -------------------------------------------------------------------------------- 1 | 13 | */ 14 | protected $except = [ 15 | 'current_password', 16 | 'password', 17 | 'password_confirmation', 18 | ]; 19 | } 20 | -------------------------------------------------------------------------------- /users-microservice/tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | get('/'); 18 | 19 | $response->assertStatus(200); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /posts-microservice/tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /users-microservice/tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /imports-microservice/tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 19 | 20 | return $app; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /posts-microservice/app/Providers/BroadcastServiceProvider.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 18 | return route('login'); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /posts-microservice/app/Http/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 18 | return route('login'); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /users-microservice/app/Http/Middleware/Authenticate.php: -------------------------------------------------------------------------------- 1 | expectsJson()) { 18 | return route('login'); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /users-microservice/app/Http/Controllers/Api/UserController.php: -------------------------------------------------------------------------------- 1 | success(User::all()); 17 | } 18 | 19 | /** 20 | * Return User Admin 21 | */ 22 | public function getUserAdmin() 23 | { 24 | return response()->success(User::where('is_admin', true)->first()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /imports-microservice/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /posts-microservice/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /users-microservice/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /posts-microservice/webpack.mix.js: -------------------------------------------------------------------------------- 1 | const mix = require('laravel-mix'); 2 | 3 | /* 4 | |-------------------------------------------------------------------------- 5 | | Mix Asset Management 6 | |-------------------------------------------------------------------------- 7 | | 8 | | Mix provides a clean, fluent API for defining some Webpack build steps 9 | | for your Laravel applications. By default, we are compiling the CSS 10 | | file for the application as well as bundling up all the JS files. 11 | | 12 | */ 13 | 14 | mix.js('resources/js/app.js', 'public/js') 15 | .postCss('resources/css/app.css', 'public/css', [ 16 | // 17 | ]); 18 | -------------------------------------------------------------------------------- /users-microservice/webpack.mix.js: -------------------------------------------------------------------------------- 1 | const mix = require('laravel-mix'); 2 | 3 | /* 4 | |-------------------------------------------------------------------------- 5 | | Mix Asset Management 6 | |-------------------------------------------------------------------------- 7 | | 8 | | Mix provides a clean, fluent API for defining some Webpack build steps 9 | | for your Laravel applications. By default, we are compiling the CSS 10 | | file for the application as well as bundling up all the JS files. 11 | | 12 | */ 13 | 14 | mix.js('resources/js/app.js', 'public/js') 15 | .postCss('resources/css/app.css', 'public/css', [ 16 | // 17 | ]); 18 | -------------------------------------------------------------------------------- /imports-microservice/webpack.mix.js: -------------------------------------------------------------------------------- 1 | const mix = require('laravel-mix'); 2 | 3 | /* 4 | |-------------------------------------------------------------------------- 5 | | Mix Asset Management 6 | |-------------------------------------------------------------------------- 7 | | 8 | | Mix provides a clean, fluent API for defining some Webpack build steps 9 | | for your Laravel applications. By default, we are compiling the CSS 10 | | file for the application as well as bundling up all the JS files. 11 | | 12 | */ 13 | 14 | mix.js('resources/js/app.js', 'public/js') 15 | .postCss('resources/css/app.css', 'public/css', [ 16 | // 17 | ]); 18 | -------------------------------------------------------------------------------- /posts-microservice/routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 18 | }); 19 | -------------------------------------------------------------------------------- /users-microservice/routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 18 | }); 19 | -------------------------------------------------------------------------------- /imports-microservice/routes/channels.php: -------------------------------------------------------------------------------- 1 | id === (int) $id; 18 | }); 19 | -------------------------------------------------------------------------------- /imports-microservice/routes/api.php: -------------------------------------------------------------------------------- 1 | name('login'); 8 | Route::get('/imports', [AdminController::class, 'getImportsToExecute']) 9 | ->name('getImportsToExecute'); 10 | 11 | /** 12 | * ADMIN ROUTES 13 | */ 14 | Route::group(['middleware' => ['auth.admin']], fn () => [ 15 | Route::post('admin/create-import', [AdminController::class, 'createImport']) 16 | ->name('create-import'), 17 | Route::post('/logout', [AuthController::class, 'logout'])->name('logout'), 18 | ]); 19 | -------------------------------------------------------------------------------- /imports-microservice/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 19 | })->purpose('Display an inspiring quote'); 20 | -------------------------------------------------------------------------------- /posts-microservice/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 19 | })->purpose('Display an inspiring quote'); 20 | -------------------------------------------------------------------------------- /users-microservice/routes/console.php: -------------------------------------------------------------------------------- 1 | comment(Inspiring::quote()); 19 | })->purpose('Display an inspiring quote'); 20 | -------------------------------------------------------------------------------- /imports-microservice/public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Send Requests To Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /posts-microservice/public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Send Requests To Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /users-microservice/public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Send Requests To Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /imports-microservice/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'password' => 'The provided password is incorrect.', 18 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 19 | 20 | ]; 21 | -------------------------------------------------------------------------------- /posts-microservice/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'password' => 'The provided password is incorrect.', 18 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 19 | 20 | ]; 21 | -------------------------------------------------------------------------------- /users-microservice/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'password' => 'The provided password is incorrect.', 18 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 19 | 20 | ]; 21 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Requests/Post/ImportedPostRequest.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'api_url' => 'required|url|unique:imports', 28 | 'frequency' => 'required|integer', 29 | ]; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /imports-microservice/app/Providers/AuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | protected $policies = [ 16 | // 'App\Models\Model' => 'App\Policies\ModelPolicy', 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | * 22 | * @return void 23 | */ 24 | public function boot() 25 | { 26 | $this->registerPolicies(); 27 | 28 | // 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /posts-microservice/app/Providers/AuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | protected $policies = [ 16 | // 'App\Models\Model' => 'App\Policies\ModelPolicy', 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | * 22 | * @return void 23 | */ 24 | public function boot() 25 | { 26 | $this->registerPolicies(); 27 | 28 | // 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /users-microservice/app/Providers/AuthServiceProvider.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | protected $policies = [ 16 | // 'App\Models\Model' => 'App\Policies\ModelPolicy', 17 | ]; 18 | 19 | /** 20 | * Register any authentication / authorization services. 21 | * 22 | * @return void 23 | */ 24 | public function boot() 25 | { 26 | $this->registerPolicies(); 27 | 28 | // 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Middleware/TrustProxies.php: -------------------------------------------------------------------------------- 1 | |string|null 14 | */ 15 | protected $proxies; 16 | 17 | /** 18 | * The headers that should be used to detect proxies. 19 | * 20 | * @var int 21 | */ 22 | protected $headers = 23 | Request::HEADER_X_FORWARDED_FOR | 24 | Request::HEADER_X_FORWARDED_HOST | 25 | Request::HEADER_X_FORWARDED_PORT | 26 | Request::HEADER_X_FORWARDED_PROTO | 27 | Request::HEADER_X_FORWARDED_AWS_ELB; 28 | } 29 | -------------------------------------------------------------------------------- /posts-microservice/app/Http/Middleware/TrustProxies.php: -------------------------------------------------------------------------------- 1 | |string|null 14 | */ 15 | protected $proxies; 16 | 17 | /** 18 | * The headers that should be used to detect proxies. 19 | * 20 | * @var int 21 | */ 22 | protected $headers = 23 | Request::HEADER_X_FORWARDED_FOR | 24 | Request::HEADER_X_FORWARDED_HOST | 25 | Request::HEADER_X_FORWARDED_PORT | 26 | Request::HEADER_X_FORWARDED_PROTO | 27 | Request::HEADER_X_FORWARDED_AWS_ELB; 28 | } 29 | -------------------------------------------------------------------------------- /users-microservice/app/Http/Middleware/TrustProxies.php: -------------------------------------------------------------------------------- 1 | |string|null 14 | */ 15 | protected $proxies; 16 | 17 | /** 18 | * The headers that should be used to detect proxies. 19 | * 20 | * @var int 21 | */ 22 | protected $headers = 23 | Request::HEADER_X_FORWARDED_FOR | 24 | Request::HEADER_X_FORWARDED_HOST | 25 | Request::HEADER_X_FORWARDED_PORT | 26 | Request::HEADER_X_FORWARDED_PROTO | 27 | Request::HEADER_X_FORWARDED_AWS_ELB; 28 | } 29 | -------------------------------------------------------------------------------- /imports-microservice/app/Jobs/TestJob.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'title' => 'required|string|max:255', 28 | 'description' => 'required', 29 | 'publication_date' => 'required|string', 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /users-microservice/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:8.1 2 | 3 | RUN apt-get update && apt-get install -y \ 4 | libfreetype6-dev \ 5 | libjpeg62-turbo-dev \ 6 | libmcrypt-dev \ 7 | libpng-dev \ 8 | zlib1g-dev \ 9 | libxml2-dev \ 10 | libzip-dev \ 11 | libonig-dev \ 12 | graphviz \ 13 | \ 14 | && docker-php-ext-configure gd \ 15 | && docker-php-ext-install -j$(nproc) gd \ 16 | && docker-php-ext-install pdo_mysql \ 17 | && docker-php-ext-install mysqli \ 18 | && docker-php-ext-install zip \ 19 | && docker-php-ext-install sockets \ 20 | && docker-php-source delete \ 21 | && curl -sS https://getcomposer.org/installer | php -- \ 22 | --install-dir=/usr/local/bin --filename=composer 23 | 24 | WORKDIR /app 25 | COPY . . 26 | RUN composer install 27 | -------------------------------------------------------------------------------- /users-microservice/app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire')->hourly(); 19 | } 20 | 21 | /** 22 | * Register the commands for the application. 23 | * 24 | * @return void 25 | */ 26 | protected function commands() 27 | { 28 | $this->load(__DIR__.'/Commands'); 29 | 30 | require base_path('routes/console.php'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /imports-microservice/app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('inspire')->hourly(); 19 | } 20 | 21 | /** 22 | * Register the commands for the application. 23 | * 24 | * @return void 25 | */ 26 | protected function commands() 27 | { 28 | $this->load(__DIR__.'/Commands'); 29 | 30 | require base_path('routes/console.php'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /imports-microservice/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Your password has been reset!', 17 | 'sent' => 'We have emailed your password reset link!', 18 | 'throttled' => 'Please wait before retrying.', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that email address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /posts-microservice/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Your password has been reset!', 17 | 'sent' => 'We have emailed your password reset link!', 18 | 'throttled' => 'Please wait before retrying.', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that email address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /users-microservice/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Your password has been reset!', 17 | 'sent' => 'We have emailed your password reset link!', 18 | 'throttled' => 'Please wait before retrying.', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that email address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /posts-microservice/app/Console/Kernel.php: -------------------------------------------------------------------------------- 1 | command('post:autoimport')->everyMinute()->withoutOverlapping(); 19 | } 20 | 21 | /** 22 | * Register the commands for the application. 23 | * 24 | * @return void 25 | */ 26 | protected function commands() 27 | { 28 | $this->load(__DIR__.'/Commands'); 29 | 30 | require base_path('routes/console.php'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /posts-microservice/app/Http/Middleware/AuthenticateUserMiddleware.php: -------------------------------------------------------------------------------- 1 | getRequest('get', 'user/authenticate'); 21 | 22 | if (!$response->ok()) { 23 | abort(401, 'unauthorized'); 24 | } 25 | 26 | return $next($request); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /posts-microservice/app/Providers/EventServiceProvider.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'name' => 'required|string|max:255', 28 | 'email' => 'required|string|email|max:255', 29 | 'password' => 'required|string|min:6', 30 | 'password_confirmation' => 'required|string|min:6|same:password', 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /posts-microservice/app/Jobs/ImportNextExecutionJob.php: -------------------------------------------------------------------------------- 1 | importInfo = $importInfo; 25 | } 26 | 27 | /** 28 | * Execute the job. 29 | * 30 | * @return void 31 | */ 32 | public function handle() 33 | { 34 | // 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /users-microservice/app/Http/Requests/Auth/RegisterRequest.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'name' => 'required|string|max:255', 28 | 'email' => 'required|string|email|max:255|unique:users', 29 | 'password' => 'required|string|min:6', 30 | 'password_confirmation' => 'required|string|min:6|same:password', 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Requests/Auth/RegisterRequest.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | public function rules() 25 | { 26 | return [ 27 | 'name' => 'required|string|max:255', 28 | 'email' => 'required|string|email|max:255|unique:users', 29 | 'password' => 'required|string|min:6', 30 | 'password_confirmation' => 'required|string|min:6|same:password', 31 | ]; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /imports-microservice/app/Jobs/ImportNextExecutionJob.php: -------------------------------------------------------------------------------- 1 | importInfo = $importInfo; 25 | } 26 | 27 | /** 28 | * Execute the job. 29 | * 30 | * @return void 31 | */ 32 | public function handle() 33 | { 34 | dd($this->importInfo); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /imports-microservice/database/migrations/2022_05_08_151552_create_imports_table.php: -------------------------------------------------------------------------------- 1 | uuid('id')->primary(); 18 | $table->string('api_url')->unique(); 19 | $table->dateTime('next_execution_time'); 20 | $table->unsignedBigInteger('frequency'); 21 | $table->timestamps(); 22 | }); 23 | } 24 | 25 | /** 26 | * Reverse the migrations. 27 | * 28 | * @return void 29 | */ 30 | public function down() 31 | { 32 | Schema::dropIfExists('imports'); 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Middleware/AdminMiddleware.php: -------------------------------------------------------------------------------- 1 | getRequest('get', 'user/authenticate'); 21 | 22 | if (!$response->ok()) { 23 | abort(401, 'Unauthorized'); 24 | } elseif (!$response->json()['data']['is_admin']) { 25 | abort(403, 'Forbidden'); 26 | } 27 | 28 | return $next($request); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /posts-microservice/database/migrations/2022_05_08_124254_create_posts_table.php: -------------------------------------------------------------------------------- 1 | uuid('id')->primary(); 18 | $table->uuid('user_id'); 19 | $table->string('title'); 20 | $table->text('description'); 21 | $table->timestamp('publication_date')->useCurrent(); 22 | $table->timestamps(); 23 | }); 24 | } 25 | 26 | /** 27 | * Reverse the migrations. 28 | * 29 | * @return void 30 | */ 31 | public function down() 32 | { 33 | Schema::dropIfExists('posts'); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /imports-microservice/app/Providers/EventServiceProvider.php: -------------------------------------------------------------------------------- 1 | $job->handle()); 23 | } 24 | 25 | /** 26 | * Determine if events and listeners should be automatically discovered. 27 | * 28 | * @return bool 29 | */ 30 | public function shouldDiscoverEvents() 31 | { 32 | return true; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /posts-microservice/routes/api.php: -------------------------------------------------------------------------------- 1 | name('register'); 8 | Route::post('login', [AuthController::class, 'login'])->name('login'); 9 | Route::get('/posts/all', [PostController::class, 'getPosts']) 10 | ->name('posts.all'); 11 | 12 | /** 13 | * USER MANAGEMENT ROUTES 14 | */ 15 | Route::group(['middleware' => ['auth.user'], 'prefix' => 'user', 'as' => 'user.'], fn () => [ 16 | Route::post('/create-post', [PostController::class, 'createPost']) 17 | ->name('create-post'), 18 | Route::get('/posts', [PostController::class, 'getUserPosts']) 19 | ->name('posts'), 20 | ]); 21 | 22 | /** 23 | * OTHER COMMON ROUTES 24 | */ 25 | Route::group(['middleware' => ['auth.user']], fn () => [ 26 | Route::post('/logout', [AuthController::class, 'logout'])->name('logout'), 27 | ]); 28 | -------------------------------------------------------------------------------- /users-microservice/README.md: -------------------------------------------------------------------------------- 1 | # About 2 | This is a microservice that will be used to perform user authentication, authorization using an Auth Service [here](https://github.com/MusahMusah/square1-user-service) that was created to seamlessly integrate with all the microservices. 3 | 4 | ## Responsibilities 5 | * Register a user 6 | * Authenticate a user 7 | * Login a user 8 | * Logout a user 9 | * Get a user's information 10 | * Distribute All Other Authentication and Authorization Features to other Microservices 11 | 12 | 13 | ## Directories and Files to Be Aware of: 14 | * `/app/Http/` - The controllers, middleware, requests and resources will be used from this directory. 15 | * `/app/Jobs/` - The jobs will be used from this directory. 16 | * `/app/Models/` - The models will be used from this directory. 17 | * `/app/Services/` - The services which extracts the business logic. 18 | * `/app/Traits/` - The traits will be used from this directory. 19 | * `/app/routes/api.php` - The routes will be used from this file. 20 | -------------------------------------------------------------------------------- /imports-microservice/config/cors.php: -------------------------------------------------------------------------------- 1 | ['api/*', 'sanctum/csrf-cookie'], 19 | 20 | 'allowed_methods' => ['*'], 21 | 22 | 'allowed_origins' => ['*'], 23 | 24 | 'allowed_origins_patterns' => [], 25 | 26 | 'allowed_headers' => ['*'], 27 | 28 | 'exposed_headers' => [], 29 | 30 | 'max_age' => 0, 31 | 32 | 'supports_credentials' => false, 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /posts-microservice/config/cors.php: -------------------------------------------------------------------------------- 1 | ['api/*', 'sanctum/csrf-cookie'], 19 | 20 | 'allowed_methods' => ['*'], 21 | 22 | 'allowed_origins' => ['*'], 23 | 24 | 'allowed_origins_patterns' => [], 25 | 26 | 'allowed_headers' => ['*'], 27 | 28 | 'exposed_headers' => [], 29 | 30 | 'max_age' => 0, 31 | 32 | 'supports_credentials' => false, 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /users-microservice/config/cors.php: -------------------------------------------------------------------------------- 1 | ['api/*', 'sanctum/csrf-cookie'], 19 | 20 | 'allowed_methods' => ['*'], 21 | 22 | 'allowed_origins' => ['*'], 23 | 24 | 'allowed_origins_patterns' => [], 25 | 26 | 'allowed_headers' => ['*'], 27 | 28 | 'exposed_headers' => [], 29 | 30 | 'max_age' => 0, 31 | 32 | 'supports_credentials' => false, 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /imports-microservice/resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | window._ = require('lodash'); 2 | 3 | /** 4 | * We'll load the axios HTTP library which allows us to easily issue requests 5 | * to our Laravel back-end. This library automatically handles sending the 6 | * CSRF token as a header based on the value of the "XSRF" token cookie. 7 | */ 8 | 9 | window.axios = require('axios'); 10 | 11 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 12 | 13 | /** 14 | * Echo exposes an expressive API for subscribing to channels and listening 15 | * for events that are broadcast by Laravel. Echo and event broadcasting 16 | * allows your team to easily build robust real-time web applications. 17 | */ 18 | 19 | // import Echo from 'laravel-echo'; 20 | 21 | // window.Pusher = require('pusher-js'); 22 | 23 | // window.Echo = new Echo({ 24 | // broadcaster: 'pusher', 25 | // key: process.env.MIX_PUSHER_APP_KEY, 26 | // cluster: process.env.MIX_PUSHER_APP_CLUSTER, 27 | // forceTLS: true 28 | // }); 29 | -------------------------------------------------------------------------------- /posts-microservice/resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | window._ = require('lodash'); 2 | 3 | /** 4 | * We'll load the axios HTTP library which allows us to easily issue requests 5 | * to our Laravel back-end. This library automatically handles sending the 6 | * CSRF token as a header based on the value of the "XSRF" token cookie. 7 | */ 8 | 9 | window.axios = require('axios'); 10 | 11 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 12 | 13 | /** 14 | * Echo exposes an expressive API for subscribing to channels and listening 15 | * for events that are broadcast by Laravel. Echo and event broadcasting 16 | * allows your team to easily build robust real-time web applications. 17 | */ 18 | 19 | // import Echo from 'laravel-echo'; 20 | 21 | // window.Pusher = require('pusher-js'); 22 | 23 | // window.Echo = new Echo({ 24 | // broadcaster: 'pusher', 25 | // key: process.env.MIX_PUSHER_APP_KEY, 26 | // cluster: process.env.MIX_PUSHER_APP_CLUSTER, 27 | // forceTLS: true 28 | // }); 29 | -------------------------------------------------------------------------------- /users-microservice/resources/js/bootstrap.js: -------------------------------------------------------------------------------- 1 | window._ = require('lodash'); 2 | 3 | /** 4 | * We'll load the axios HTTP library which allows us to easily issue requests 5 | * to our Laravel back-end. This library automatically handles sending the 6 | * CSRF token as a header based on the value of the "XSRF" token cookie. 7 | */ 8 | 9 | window.axios = require('axios'); 10 | 11 | window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; 12 | 13 | /** 14 | * Echo exposes an expressive API for subscribing to channels and listening 15 | * for events that are broadcast by Laravel. Echo and event broadcasting 16 | * allows your team to easily build robust real-time web applications. 17 | */ 18 | 19 | // import Echo from 'laravel-echo'; 20 | 21 | // window.Pusher = require('pusher-js'); 22 | 23 | // window.Echo = new Echo({ 24 | // broadcaster: 'pusher', 25 | // key: process.env.MIX_PUSHER_APP_KEY, 26 | // cluster: process.env.MIX_PUSHER_APP_CLUSTER, 27 | // forceTLS: true 28 | // }); 29 | -------------------------------------------------------------------------------- /imports-microservice/database/migrations/2019_08_19_000000_create_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('uuid')->unique(); 19 | $table->text('connection'); 20 | $table->text('queue'); 21 | $table->longText('payload'); 22 | $table->longText('exception'); 23 | $table->timestamp('failed_at')->useCurrent(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('failed_jobs'); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /posts-microservice/database/migrations/2019_08_19_000000_create_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('uuid')->unique(); 19 | $table->text('connection'); 20 | $table->text('queue'); 21 | $table->longText('payload'); 22 | $table->longText('exception'); 23 | $table->timestamp('failed_at')->useCurrent(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('failed_jobs'); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /users-microservice/database/migrations/2019_08_19_000000_create_failed_jobs_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('uuid')->unique(); 19 | $table->text('connection'); 20 | $table->text('queue'); 21 | $table->longText('payload'); 22 | $table->longText('exception'); 23 | $table->timestamp('failed_at')->useCurrent(); 24 | }); 25 | } 26 | 27 | /** 28 | * Reverse the migrations. 29 | * 30 | * @return void 31 | */ 32 | public function down() 33 | { 34 | Schema::dropIfExists('failed_jobs'); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 26 | return redirect(RouteServiceProvider::HOME); 27 | } 28 | } 29 | 30 | return $next($request); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /posts-microservice/app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 26 | return redirect(RouteServiceProvider::HOME); 27 | } 28 | } 29 | 30 | return $next($request); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /users-microservice/app/Http/Middleware/RedirectIfAuthenticated.php: -------------------------------------------------------------------------------- 1 | check()) { 26 | return redirect(RouteServiceProvider::HOME); 27 | } 28 | } 29 | 30 | return $next($request); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /imports-microservice/app/Traits/HasUuid.php: -------------------------------------------------------------------------------- 1 | {$model->getKeyName()} = Str::uuid()->toString(); 20 | }); 21 | } 22 | 23 | /** 24 | * Get the value indicating whether the IDs are incrementing. 25 | * 26 | * @return bool 27 | */ 28 | public function getIncrementing() 29 | { 30 | return false; 31 | } 32 | 33 | /** 34 | * Get the primary key for the model. 35 | * 36 | * @return string 37 | */ 38 | public function getKeyName() 39 | { 40 | return 'id'; 41 | } 42 | 43 | /** 44 | * Get the auto-incrementing key type. 45 | * 46 | * @return string 47 | */ 48 | public function getKeyType() 49 | { 50 | return 'string'; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /posts-microservice/app/Traits/HasUuid.php: -------------------------------------------------------------------------------- 1 | {$model->getKeyName()} = Str::uuid()->toString(); 20 | }); 21 | } 22 | 23 | /** 24 | * Get the value indicating whether the IDs are incrementing. 25 | * 26 | * @return bool 27 | */ 28 | public function getIncrementing() 29 | { 30 | return false; 31 | } 32 | 33 | /** 34 | * Get the primary key for the model. 35 | * 36 | * @return string 37 | */ 38 | public function getKeyName() 39 | { 40 | return 'id'; 41 | } 42 | 43 | /** 44 | * Get the auto-incrementing key type. 45 | * 46 | * @return string 47 | */ 48 | public function getKeyType() 49 | { 50 | return 'string'; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /users-microservice/app/Traits/HasUuid.php: -------------------------------------------------------------------------------- 1 | {$model->getKeyName()} = Str::uuid()->toString(); 20 | }); 21 | } 22 | 23 | /** 24 | * Get the value indicating whether the IDs are incrementing. 25 | * 26 | * @return bool 27 | */ 28 | public function getIncrementing() 29 | { 30 | return false; 31 | } 32 | 33 | /** 34 | * Get the primary key for the model. 35 | * 36 | * @return string 37 | */ 38 | public function getKeyName() 39 | { 40 | return 'id'; 41 | } 42 | 43 | /** 44 | * Get the auto-incrementing key type. 45 | * 46 | * @return string 47 | */ 48 | public function getKeyType() 49 | { 50 | return 'string'; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /users-microservice/database/migrations/2014_10_12_000000_create_users_table.php: -------------------------------------------------------------------------------- 1 | uuid('id')->primary(); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->boolean('is_admin')->default(false); 21 | $table->timestamp('email_verified_at')->nullable(); 22 | $table->string('password'); 23 | $table->rememberToken(); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('users'); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /imports-microservice/app/Jobs/AutoImportPostJob.php: -------------------------------------------------------------------------------- 1 | importInfo = $importInfo; 27 | } 28 | 29 | /** 30 | * Execute the job. 31 | * 32 | * @return void 33 | */ 34 | public function handle(ImportService $importService) 35 | { 36 | // update import next_execute_time 37 | $importService->updateNextExecutionTime($this->importInfo['id']); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /users-microservice/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('tokenable_type'); 19 | $table->uuid('tokenable_id'); 20 | $table->string('name'); 21 | $table->string('token', 64)->unique(); 22 | $table->text('abilities')->nullable(); 23 | $table->timestamp('last_used_at')->nullable(); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('personal_access_tokens'); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /posts-microservice/config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | 'scheme' => 'https', 22 | ], 23 | 24 | 'postmark' => [ 25 | 'token' => env('POSTMARK_TOKEN'), 26 | ], 27 | 28 | 'ses' => [ 29 | 'key' => env('AWS_ACCESS_KEY_ID'), 30 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 31 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 32 | ], 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /users-microservice/config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | 'scheme' => 'https', 22 | ], 23 | 24 | 'postmark' => [ 25 | 'token' => env('POSTMARK_TOKEN'), 26 | ], 27 | 28 | 'ses' => [ 29 | 'key' => env('AWS_ACCESS_KEY_ID'), 30 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 31 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 32 | ], 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /imports-microservice/config/services.php: -------------------------------------------------------------------------------- 1 | [ 18 | 'domain' => env('MAILGUN_DOMAIN'), 19 | 'secret' => env('MAILGUN_SECRET'), 20 | 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), 21 | 'scheme' => 'https', 22 | ], 23 | 24 | 'postmark' => [ 25 | 'token' => env('POSTMARK_TOKEN'), 26 | ], 27 | 28 | 'ses' => [ 29 | 'key' => env('AWS_ACCESS_KEY_ID'), 30 | 'secret' => env('AWS_SECRET_ACCESS_KEY'), 31 | 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 32 | ], 33 | 34 | ]; 35 | -------------------------------------------------------------------------------- /users-microservice/app/Providers/EventServiceProvider.php: -------------------------------------------------------------------------------- 1 | > 16 | */ 17 | protected $listen = [ 18 | Registered::class => [ 19 | SendEmailVerificationNotification::class, 20 | ], 21 | ]; 22 | 23 | /** 24 | * Register any events for your application. 25 | * 26 | * @return void 27 | */ 28 | public function boot() 29 | { 30 | // 31 | } 32 | 33 | /** 34 | * Determine if events and listeners should be automatically discovered. 35 | * 36 | * @return bool 37 | */ 38 | public function shouldDiscoverEvents() 39 | { 40 | return false; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /posts-microservice/.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY= 4 | APP_DEBUG=true 5 | APP_URL=http://localhost 6 | 7 | LOG_CHANNEL=stack 8 | LOG_DEPRECATIONS_CHANNEL=null 9 | LOG_LEVEL=debug 10 | 11 | DB_CONNECTION=mysql 12 | DB_HOST=127.0.0.1 13 | DB_PORT=3306 14 | DB_DATABASE=posts_microservice 15 | DB_USERNAME=root 16 | DB_PASSWORD= 17 | 18 | BROADCAST_DRIVER=log 19 | CACHE_DRIVER=file 20 | FILESYSTEM_DISK=local 21 | QUEUE_CONNECTION=sync 22 | SESSION_DRIVER=file 23 | SESSION_LIFETIME=120 24 | 25 | MEMCACHED_HOST=127.0.0.1 26 | 27 | REDIS_HOST=127.0.0.1 28 | REDIS_PASSWORD=null 29 | REDIS_PORT=6379 30 | 31 | MAIL_MAILER=smtp 32 | MAIL_HOST=mailhog 33 | MAIL_PORT=1025 34 | MAIL_USERNAME=null 35 | MAIL_PASSWORD=null 36 | MAIL_ENCRYPTION=null 37 | MAIL_FROM_ADDRESS="hello@example.com" 38 | MAIL_FROM_NAME="${APP_NAME}" 39 | 40 | AWS_ACCESS_KEY_ID= 41 | AWS_SECRET_ACCESS_KEY= 42 | AWS_DEFAULT_REGION=us-east-1 43 | AWS_BUCKET= 44 | AWS_USE_PATH_STYLE_ENDPOINT=false 45 | 46 | PUSHER_APP_ID= 47 | PUSHER_APP_KEY= 48 | PUSHER_APP_SECRET= 49 | PUSHER_APP_CLUSTER=mt1 50 | 51 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 52 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 53 | -------------------------------------------------------------------------------- /users-microservice/.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY= 4 | APP_DEBUG=true 5 | APP_URL=http://localhost 6 | 7 | LOG_CHANNEL=stack 8 | LOG_DEPRECATIONS_CHANNEL=null 9 | LOG_LEVEL=debug 10 | 11 | DB_CONNECTION=mysql 12 | DB_HOST=127.0.0.1 13 | DB_PORT=3306 14 | DB_DATABASE=users_microservice 15 | DB_USERNAME=root 16 | DB_PASSWORD= 17 | 18 | BROADCAST_DRIVER=log 19 | CACHE_DRIVER=file 20 | FILESYSTEM_DISK=local 21 | QUEUE_CONNECTION=sync 22 | SESSION_DRIVER=file 23 | SESSION_LIFETIME=120 24 | 25 | MEMCACHED_HOST=127.0.0.1 26 | 27 | REDIS_HOST=127.0.0.1 28 | REDIS_PASSWORD=null 29 | REDIS_PORT=6379 30 | 31 | MAIL_MAILER=smtp 32 | MAIL_HOST=mailhog 33 | MAIL_PORT=1025 34 | MAIL_USERNAME=null 35 | MAIL_PASSWORD=null 36 | MAIL_ENCRYPTION=null 37 | MAIL_FROM_ADDRESS="hello@example.com" 38 | MAIL_FROM_NAME="${APP_NAME}" 39 | 40 | AWS_ACCESS_KEY_ID= 41 | AWS_SECRET_ACCESS_KEY= 42 | AWS_DEFAULT_REGION=us-east-1 43 | AWS_BUCKET= 44 | AWS_USE_PATH_STYLE_ENDPOINT=false 45 | 46 | PUSHER_APP_ID= 47 | PUSHER_APP_KEY= 48 | PUSHER_APP_SECRET= 49 | PUSHER_APP_CLUSTER=mt1 50 | 51 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 52 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 53 | -------------------------------------------------------------------------------- /imports-microservice/.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME=Laravel 2 | APP_ENV=local 3 | APP_KEY= 4 | APP_DEBUG=true 5 | APP_URL=http://localhost 6 | 7 | LOG_CHANNEL=stack 8 | LOG_DEPRECATIONS_CHANNEL=null 9 | LOG_LEVEL=debug 10 | 11 | DB_CONNECTION=mysql 12 | DB_HOST=127.0.0.1 13 | DB_PORT=3306 14 | DB_DATABASE=imports_microservice 15 | DB_USERNAME=root 16 | DB_PASSWORD= 17 | 18 | BROADCAST_DRIVER=log 19 | CACHE_DRIVER=file 20 | FILESYSTEM_DISK=local 21 | QUEUE_CONNECTION=sync 22 | SESSION_DRIVER=file 23 | SESSION_LIFETIME=120 24 | 25 | MEMCACHED_HOST=127.0.0.1 26 | 27 | REDIS_HOST=127.0.0.1 28 | REDIS_PASSWORD=null 29 | REDIS_PORT=6379 30 | 31 | MAIL_MAILER=smtp 32 | MAIL_HOST=mailhog 33 | MAIL_PORT=1025 34 | MAIL_USERNAME=null 35 | MAIL_PASSWORD=null 36 | MAIL_ENCRYPTION=null 37 | MAIL_FROM_ADDRESS="hello@example.com" 38 | MAIL_FROM_NAME="${APP_NAME}" 39 | 40 | AWS_ACCESS_KEY_ID= 41 | AWS_SECRET_ACCESS_KEY= 42 | AWS_DEFAULT_REGION=us-east-1 43 | AWS_BUCKET= 44 | AWS_USE_PATH_STYLE_ENDPOINT=false 45 | 46 | PUSHER_APP_ID= 47 | PUSHER_APP_KEY= 48 | PUSHER_APP_SECRET= 49 | PUSHER_APP_CLUSTER=mt1 50 | 51 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 52 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 53 | -------------------------------------------------------------------------------- /posts-microservice/config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => env( 32 | 'VIEW_COMPILED_PATH', 33 | realpath(storage_path('framework/views')) 34 | ), 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /users-microservice/config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => env( 32 | 'VIEW_COMPILED_PATH', 33 | realpath(storage_path('framework/views')) 34 | ), 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /imports-microservice/config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => env( 32 | 'VIEW_COMPILED_PATH', 33 | realpath(storage_path('framework/views')) 34 | ), 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /imports-microservice/database/migrations/2022_05_08_203035_create_job_batches_table.php: -------------------------------------------------------------------------------- 1 | string('id')->primary(); 18 | $table->string('name'); 19 | $table->integer('total_jobs'); 20 | $table->integer('pending_jobs'); 21 | $table->integer('failed_jobs'); 22 | $table->text('failed_job_ids'); 23 | $table->mediumText('options')->nullable(); 24 | $table->integer('cancelled_at')->nullable(); 25 | $table->integer('created_at'); 26 | $table->integer('finished_at')->nullable(); 27 | }); 28 | } 29 | 30 | /** 31 | * Reverse the migrations. 32 | * 33 | * @return void 34 | */ 35 | public function down() 36 | { 37 | Schema::dropIfExists('job_batches'); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /posts-microservice/database/migrations/2022_05_11_071936_create_job_batches_table.php: -------------------------------------------------------------------------------- 1 | string('id')->primary(); 18 | $table->string('name'); 19 | $table->integer('total_jobs'); 20 | $table->integer('pending_jobs'); 21 | $table->integer('failed_jobs'); 22 | $table->text('failed_job_ids'); 23 | $table->mediumText('options')->nullable(); 24 | $table->integer('cancelled_at')->nullable(); 25 | $table->integer('created_at'); 26 | $table->integer('finished_at')->nullable(); 27 | }); 28 | } 29 | 30 | /** 31 | * Reverse the migrations. 32 | * 33 | * @return void 34 | */ 35 | public function down() 36 | { 37 | Schema::dropIfExists('job_batches'); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /posts-microservice/database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | class UserFactory extends Factory 12 | { 13 | /** 14 | * Define the model's default state. 15 | * 16 | * @return array 17 | */ 18 | public function definition() 19 | { 20 | return [ 21 | 'name' => $this->faker->name(), 22 | 'email' => $this->faker->unique()->safeEmail(), 23 | 'email_verified_at' => now(), 24 | 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password 25 | 'remember_token' => Str::random(10), 26 | ]; 27 | } 28 | 29 | /** 30 | * Indicate that the model's email address should be unverified. 31 | * 32 | * @return static 33 | */ 34 | public function unverified() 35 | { 36 | return $this->state(function (array $attributes) { 37 | return [ 38 | 'email_verified_at' => null, 39 | ]; 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /users-microservice/database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | 11 | */ 12 | class UserFactory extends Factory 13 | { 14 | /** 15 | * Define the model's default state. 16 | * 17 | * @return array 18 | */ 19 | public function definition() 20 | { 21 | return [ 22 | 'name' => 'Admin User', 23 | 'email' => 'admin@admin.com', 24 | 'is_admin' => true, 25 | 'email_verified_at' => now(), 26 | 'password' => Hash::make('admin'), // admin 27 | 'remember_token' => Str::random(10), 28 | ]; 29 | } 30 | 31 | /** 32 | * Indicate that the model's email address should be unverified. 33 | * 34 | * @return static 35 | */ 36 | public function unverified() 37 | { 38 | return $this->state(function (array $attributes) { 39 | return [ 40 | 'email_verified_at' => null, 41 | ]; 42 | }); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /users-microservice/routes/api.php: -------------------------------------------------------------------------------- 1 | name('register'); 9 | Route::post('login', [AuthController::class, 'login'])->name('login'); 10 | 11 | /** 12 | * USER MANAGEMENT ROUTES 13 | */ 14 | Route::group(['middleware' => ['auth:sanctum'], 'as' => 'user.'], fn () => [ 15 | Route::get('/user', fn () => response()->success(auth()->user(), 'User Information retrieved successfully.')) 16 | ->name('info'), 17 | Route::get('/user/authenticate', [AuthController::class, 'authenticate']) 18 | ->name('authenticate'), 19 | Route::post('/logout', [AuthController::class, 'logout'])->name('logout'), 20 | ]); 21 | 22 | /** 23 | * ADMINISTRATOR MANAGEMENT ROUTES 24 | */ 25 | Route::group(['middleware' => [], 'as' => 'admin.'], fn () => [ 26 | Route::get('/getUsers', [UserController::class, 'getUsers']) 27 | ->name('getUsers'), 28 | Route::get('/getUserAdmin', [UserController::class, 'getUserAdmin']) 29 | ->name('getUserAdmin'), 30 | 31 | ]); 32 | 33 | -------------------------------------------------------------------------------- /posts-microservice/app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | , \Psr\Log\LogLevel::*> 14 | */ 15 | protected $levels = [ 16 | // 17 | ]; 18 | 19 | /** 20 | * A list of the exception types that are not reported. 21 | * 22 | * @var array> 23 | */ 24 | protected $dontReport = [ 25 | // 26 | ]; 27 | 28 | /** 29 | * A list of the inputs that are never flashed for validation exceptions. 30 | * 31 | * @var array 32 | */ 33 | protected $dontFlash = [ 34 | 'current_password', 35 | 'password', 36 | 'password_confirmation', 37 | ]; 38 | 39 | /** 40 | * Register the exception handling callbacks for the application. 41 | * 42 | * @return void 43 | */ 44 | public function register() 45 | { 46 | $this->reportable(function (Throwable $e) { 47 | // 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /users-microservice/app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | , \Psr\Log\LogLevel::*> 14 | */ 15 | protected $levels = [ 16 | // 17 | ]; 18 | 19 | /** 20 | * A list of the exception types that are not reported. 21 | * 22 | * @var array> 23 | */ 24 | protected $dontReport = [ 25 | // 26 | ]; 27 | 28 | /** 29 | * A list of the inputs that are never flashed for validation exceptions. 30 | * 31 | * @var array 32 | */ 33 | protected $dontFlash = [ 34 | 'current_password', 35 | 'password', 36 | 'password_confirmation', 37 | ]; 38 | 39 | /** 40 | * Register the exception handling callbacks for the application. 41 | * 42 | * @return void 43 | */ 44 | public function register() 45 | { 46 | $this->reportable(function (Throwable $e) { 47 | // 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /imports-microservice/app/Exceptions/Handler.php: -------------------------------------------------------------------------------- 1 | , \Psr\Log\LogLevel::*> 14 | */ 15 | protected $levels = [ 16 | // 17 | ]; 18 | 19 | /** 20 | * A list of the exception types that are not reported. 21 | * 22 | * @var array> 23 | */ 24 | protected $dontReport = [ 25 | // 26 | ]; 27 | 28 | /** 29 | * A list of the inputs that are never flashed for validation exceptions. 30 | * 31 | * @var array 32 | */ 33 | protected $dontFlash = [ 34 | 'current_password', 35 | 'password', 36 | 'password_confirmation', 37 | ]; 38 | 39 | /** 40 | * Register the exception handling callbacks for the application. 41 | * 42 | * @return void 43 | */ 44 | public function register() 45 | { 46 | $this->reportable(function (Throwable $e) { 47 | // 48 | }); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /users-microservice/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | users-microservice: 4 | container_name: users-microservice 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | environment: 9 | DB_HOST: users-microservice_db 10 | DB_DATABASE: users-microservice 11 | DB_USERNAME: root 12 | DB_PASSWORD: root 13 | command: 'php artisan serve --host=0.0.0.0' 14 | networks: 15 | - users-microservice 16 | volumes: 17 | - .:/app 18 | ports: 19 | - 8081:8000 20 | depends_on: 21 | - users-microservice_db 22 | 23 | users-microservice_db: 24 | platform: linux/x86_64 25 | image: mysql:5.7 26 | restart: always 27 | environment: 28 | MYSQL_DATABASE: users-microservice 29 | # MYSQL_USER: root 30 | MYSQL_PASSWORD: root 31 | MYSQL_ROOT_PASSWORD: root 32 | networks: 33 | - users-microservice 34 | volumes: 35 | - db-data:/var/lib/mysql 36 | ports: 37 | - 33070:3306 38 | 39 | networks: 40 | users-microservice: 41 | name: users-microservice 42 | 43 | volumes: 44 | db-data: 45 | -------------------------------------------------------------------------------- /imports-microservice/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | ./tests/Unit 10 | 11 | 12 | ./tests/Feature 13 | 14 | 15 | 16 | 17 | ./app 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /posts-microservice/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | ./tests/Unit 10 | 11 | 12 | ./tests/Feature 13 | 14 | 15 | 16 | 17 | ./app 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /users-microservice/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | ./tests/Unit 10 | 11 | 12 | ./tests/Feature 13 | 14 | 15 | 16 | 17 | ./app 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /users-microservice/app/Models/User.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | protected $fillable = [ 20 | 'name', 21 | 'email', 22 | 'password', 23 | 'is_admin' 24 | ]; 25 | 26 | /** 27 | * The attributes that should be hidden for serialization. 28 | * 29 | * @var array 30 | */ 31 | protected $hidden = [ 32 | 'password', 33 | 'remember_token', 34 | 'email_verified_at', 35 | 'updated_at', 36 | ]; 37 | 38 | /** 39 | * The attributes that should be cast. 40 | * 41 | * @var array 42 | */ 43 | protected $casts = [ 44 | 'email_verified_at' => 'datetime', 45 | 'is_admin' => 'boolean', 46 | ]; 47 | 48 | /** 49 | * MODEL METHODS 50 | */ 51 | public function isAdmin() : bool 52 | { 53 | return $this->is_admin; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /posts-microservice/app/Jobs/AutoImportPostJob.php: -------------------------------------------------------------------------------- 1 | importInfo = $importInfo; 28 | } 29 | 30 | /** 31 | * Execute the job. 32 | * 33 | * @return void 34 | */ 35 | public function handle(PostService $postService) 36 | { 37 | // make an external request to the post import url 38 | $request = Http::get($this->importInfo['api_url']); 39 | // get the response body 40 | if ($request->successful()) { 41 | // insert the data into the database 42 | $postService->importMultiplePosts($request->collect()['data']); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /imports-microservice/app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | json([ 30 | 'success' => true, 31 | 'message' => $message, 32 | ], $status_code); 33 | } 34 | return response()->json([ 35 | 'success' => true, 36 | 'message' => $message, 37 | 'data' => $data, 38 | ], $status_code); 39 | }); 40 | 41 | Response::macro('error', function ($error, $message = null, int $status_code = 400) { 42 | return response()->json([ 43 | 'success' => false, 44 | 'message' => $message, 45 | 'error' => $error, 46 | ], $status_code); 47 | }); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /posts-microservice/app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | json([ 30 | 'success' => true, 31 | 'message' => $message, 32 | ], $status_code); 33 | } 34 | return response()->json([ 35 | 'success' => true, 36 | 'message' => $message, 37 | 'data' => $data, 38 | ], $status_code); 39 | }); 40 | 41 | Response::macro('error', function ($error, $message = null, int $status_code = 400) { 42 | return response()->json([ 43 | 'success' => false, 44 | 'message' => $message, 45 | 'error' => $error, 46 | ], $status_code); 47 | }); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /users-microservice/app/Providers/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | json([ 30 | 'success' => true, 31 | 'message' => $message, 32 | ], $status_code); 33 | } 34 | return response()->json([ 35 | 'success' => true, 36 | 'message' => $message, 37 | 'data' => $data, 38 | ], $status_code); 39 | }); 40 | 41 | Response::macro('error', function ($error, $message = null, int $status_code = 400) { 42 | return response()->json([ 43 | 'success' => false, 44 | 'message' => $message, 45 | 'error' => $error, 46 | ], $status_code); 47 | }); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /imports-microservice/README.md: -------------------------------------------------------------------------------- 1 | # About 2 | This is a microservice that will be used to perform posts import from [here](https://sq1-api-test.herokuapp.com/posts) upon job event triggered from Post Microservice. It is also 3 | connected to a docker network that will be used to connect to the User Microservice. 4 | 5 | ## Responsibilities 6 | * Create a new Import by Admin User 7 | * Communicate with User Microservice to get the user information 8 | * Communicate with Post Microservice to send import whose next_execution_date is less than current date 9 | 10 | ## Directories and Files to Be Aware of: 11 | * `/app/Console/Commands/AutoImportPost.php` - The command that will be used to trigger the job. 12 | * `/app/Http/` - The controllers, middleware, requests and resources will be used from this directory. 13 | * `/app/Jobs/` - The jobs will be used from this directory. 14 | * `/app/Models/` - The models will be used from this directory. 15 | * `/app/Services/` - The services which extracts the business logic. 16 | * `/app/Traits/` - The traits will be used from this directory. 17 | * `/app/routes/api.php` - The routes will be used from this file. 18 | 19 | ## Api Endpoints 20 | The application is built with RESTful API endpoints. No frontend is built due to the simplicity of the application and time constraints. 21 | 22 | ### The Login Endpoint 23 | ![img_1.png](img_1.png) 24 | 25 | ### Logout Endpoint 26 | ![img_2.png](img_2.png) 27 | 28 | ### Create Import Endpoint 29 | ![img_3.png](img_3.png) 30 | 31 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Controllers/Api/AdminController.php: -------------------------------------------------------------------------------- 1 | importService = $importService; 16 | } 17 | 18 | /** 19 | * Save Import Posts from external source. 20 | */ 21 | public function createImport(ImportedPostRequest $request) 22 | { 23 | try { 24 | $import = $this->importService->createImport($request->validated()); 25 | return response()->success($import, 'Posts import created successfully'); 26 | } catch (\Exception $exception) { 27 | return response()->error($exception->getMessage(), 'Posts import failed'); 28 | } 29 | } 30 | 31 | /** 32 | * Get Imports to Execute. 33 | */ 34 | public function getImportsToExecute(Request $request) 35 | { 36 | try { 37 | $imports = $this->importService->getImportsToExecute(); 38 | return response()->success($imports, 'Imports to execute found'); 39 | } catch (\Exception $exception) { 40 | return response()->error($exception->getMessage(), 'Imports to execute not found'); 41 | } 42 | 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /imports-microservice/app/Services/PostService.php: -------------------------------------------------------------------------------- 1 | create([ 15 | 'title' => $data['title'], 16 | 'description' => $data['description'], 17 | 'user_id' => auth()->id(), 18 | 'publication_date' => $data['publication_date'], 19 | ]); 20 | } 21 | 22 | // Get single user post 23 | public function getUserPosts(string $sortBy) : Model 24 | { 25 | // fetch all user post and sort by publication_date 26 | return auth()->user()->posts()->orderBy('publication_date', $sortBy)->get(); 27 | } 28 | 29 | // Create multiple posts for admin user 30 | public function importMultiplePosts($data) : bool 31 | { 32 | // get admin User 33 | $adminUser = User::query()->where('is_admin', true)->first(); 34 | 35 | // import multiple posts for admin user 36 | collect($data)->each(function ($post) use ($adminUser) { 37 | Post::query()->create([ 38 | 'title' => $post['title'], 39 | 'description' => $post['description'], 40 | 'user_id' => $adminUser->id, 41 | 'publication_date' => $post['publication_date'], 42 | ]); 43 | }); 44 | 45 | return true; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /imports-microservice/app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | configureRateLimiting(); 30 | 31 | $this->routes(function () { 32 | Route::middleware('api') 33 | ->prefix('api') 34 | ->group(base_path('routes/api.php')); 35 | 36 | Route::middleware('web') 37 | ->group(base_path('routes/web.php')); 38 | }); 39 | } 40 | 41 | /** 42 | * Configure the rate limiters for the application. 43 | * 44 | * @return void 45 | */ 46 | protected function configureRateLimiting() 47 | { 48 | RateLimiter::for('api', function (Request $request) { 49 | return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); 50 | }); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /posts-microservice/app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | configureRateLimiting(); 30 | 31 | $this->routes(function () { 32 | Route::middleware('api') 33 | ->prefix('api') 34 | ->group(base_path('routes/api.php')); 35 | 36 | Route::middleware('web') 37 | ->group(base_path('routes/web.php')); 38 | }); 39 | } 40 | 41 | /** 42 | * Configure the rate limiters for the application. 43 | * 44 | * @return void 45 | */ 46 | protected function configureRateLimiting() 47 | { 48 | RateLimiter::for('api', function (Request $request) { 49 | return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); 50 | }); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /users-microservice/app/Providers/RouteServiceProvider.php: -------------------------------------------------------------------------------- 1 | configureRateLimiting(); 30 | 31 | $this->routes(function () { 32 | Route::middleware('api') 33 | ->prefix('api') 34 | ->group(base_path('routes/api.php')); 35 | 36 | Route::middleware('web') 37 | ->group(base_path('routes/web.php')); 38 | }); 39 | } 40 | 41 | /** 42 | * Configure the rate limiters for the application. 43 | * 44 | * @return void 45 | */ 46 | protected function configureRateLimiting() 47 | { 48 | RateLimiter::for('api', function (Request $request) { 49 | return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); 50 | }); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /imports-microservice/app/Http/Controllers/Api/AuthController.php: -------------------------------------------------------------------------------- 1 | userService = $userService; 17 | } 18 | 19 | public function login(Request $request) 20 | { 21 | try { 22 | $response = $this->userService->post("login", $request->all()); 23 | 24 | $cookie = cookie('jwt', $response['data']['accessToken'], 60 * 24); // 1 day 25 | 26 | return response([ 27 | 'message' => 'User logged in successfully, cookie set.' 28 | ])->withCookie($cookie); 29 | } catch (\Exception $e) { 30 | return response([ 31 | 'message' => json_decode($e->getMessage()) 32 | ], Response::HTTP_BAD_REQUEST); 33 | } 34 | } 35 | 36 | public function logout() 37 | { 38 | try { 39 | $cookie = \Cookie::forget('jwt'); 40 | 41 | $this->userService->post('logout', []); 42 | 43 | return response([ 44 | 'message' => 'User logged out successfully, cookie deleted.' 45 | ])->withCookie($cookie); 46 | } 47 | catch (\Exception $e) { 48 | return response()->error(json_decode($e->getMessage()), Response::HTTP_UNAUTHORIZED); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /posts-microservice/README.md: -------------------------------------------------------------------------------- 1 | # About 2 | This is a microservice that will be used to store and retrieve posts. It is also 3 | connected to a docker network that will be used to connect to the User Microservice. 4 | 5 | ## Responsibilities 6 | * Store posts 7 | * Retrieve posts 8 | * Connect to the User Microservice 9 | * Connect to the Docker Network 10 | * Connect to a Redis Cache 11 | * Trigger job events for automated posts import using schedular / cron job. 12 | * Autoimport posts from a remote source. 13 | 14 | ## Directories and Files to Be Aware of: 15 | * `/app/Console/Commands/AutoImportPost.php` - The command that will be used to trigger the job. 16 | * `/app/Console/Kernel.php` - cron job will be triggered from this file. 17 | * `/app/Http/` - The controllers, middleware, requests and resources will be used from this directory. 18 | * `/app/Jobs/` - The jobs will be used from this directory. 19 | * `/app/Models/` - The models will be used from this directory. 20 | * `/app/Services/` - The services which extracts the business logic. 21 | * `/app/Traits/` - The traits will be used from this directory. 22 | * `/app/routes/api.php` - The routes will be used from this file. 23 | 24 | ## Api Endpoints 25 | The application is built with RESTful API endpoints. No frontend is built due to the simplicity of the application and time constraints. 26 | 27 | ### The Login Endpoint 28 | ![img.png](img.png) 29 | 30 | ### Logout Endpoint 31 | ![img_1.png](img_1.png) 32 | 33 | ### New User Registration Endpoint 34 | ![img_2.png](img_2.png) 35 | 36 | ### User Create Post 37 | ![img_3.png](img_3.png) 38 | 39 | ### User's Posts 40 | ![img_4.png](img_4.png) 41 | 42 | ### Get all posts 43 | ![img_5.png](img_5.png) 44 | -------------------------------------------------------------------------------- /imports-microservice/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | imports-microservice: 4 | container_name: imports-microservice 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | environment: 9 | DB_HOST: imports-microservice_db 10 | DB_DATABASE: imports-microservice 11 | DB_USERNAME: root 12 | DB_PASSWORD: root 13 | command: 'php artisan serve --host=0.0.0.0' 14 | networks: 15 | - imports-microservice 16 | - users-microservice 17 | volumes: 18 | - .:/app 19 | ports: 20 | - 8083:8000 21 | depends_on: 22 | - imports-microservice_db 23 | 24 | imports-microservice_queue: 25 | build: . 26 | command: 'php artisan queue:work' 27 | restart: unless-stopped 28 | environment: 29 | CACHE_DRIVER: file 30 | depends_on: 31 | - imports-microservice_db 32 | networks: 33 | - imports-microservice 34 | 35 | imports-microservice_db: 36 | platform: linux/x86_64 37 | image: mysql:5.7 38 | restart: always 39 | environment: 40 | MYSQL_DATABASE: imports-microservice 41 | # MYSQL_USER: root 42 | MYSQL_PASSWORD: root 43 | MYSQL_ROOT_PASSWORD: root 44 | networks: 45 | - imports-microservice 46 | volumes: 47 | - db-data:/var/lib/mysql 48 | ports: 49 | - 33072:3306 50 | 51 | networks: 52 | imports-microservice: 53 | name: imports-microservice 54 | users-microservice: 55 | external: 56 | name: users-microservice 57 | 58 | volumes: 59 | db-data: 60 | -------------------------------------------------------------------------------- /imports-microservice/config/hashing.php: -------------------------------------------------------------------------------- 1 | 'bcrypt', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Bcrypt Options 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may specify the configuration options that should be used when 26 | | passwords are hashed using the Bcrypt algorithm. This will allow you 27 | | to control the amount of time it takes to hash the given password. 28 | | 29 | */ 30 | 31 | 'bcrypt' => [ 32 | 'rounds' => env('BCRYPT_ROUNDS', 10), 33 | ], 34 | 35 | /* 36 | |-------------------------------------------------------------------------- 37 | | Argon Options 38 | |-------------------------------------------------------------------------- 39 | | 40 | | Here you may specify the configuration options that should be used when 41 | | passwords are hashed using the Argon algorithm. These will allow you 42 | | to control the amount of time it takes to hash the given password. 43 | | 44 | */ 45 | 46 | 'argon' => [ 47 | 'memory' => 65536, 48 | 'threads' => 1, 49 | 'time' => 4, 50 | ], 51 | 52 | ]; 53 | -------------------------------------------------------------------------------- /posts-microservice/config/hashing.php: -------------------------------------------------------------------------------- 1 | 'bcrypt', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Bcrypt Options 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may specify the configuration options that should be used when 26 | | passwords are hashed using the Bcrypt algorithm. This will allow you 27 | | to control the amount of time it takes to hash the given password. 28 | | 29 | */ 30 | 31 | 'bcrypt' => [ 32 | 'rounds' => env('BCRYPT_ROUNDS', 10), 33 | ], 34 | 35 | /* 36 | |-------------------------------------------------------------------------- 37 | | Argon Options 38 | |-------------------------------------------------------------------------- 39 | | 40 | | Here you may specify the configuration options that should be used when 41 | | passwords are hashed using the Argon algorithm. These will allow you 42 | | to control the amount of time it takes to hash the given password. 43 | | 44 | */ 45 | 46 | 'argon' => [ 47 | 'memory' => 65536, 48 | 'threads' => 1, 49 | 'time' => 4, 50 | ], 51 | 52 | ]; 53 | -------------------------------------------------------------------------------- /users-microservice/config/hashing.php: -------------------------------------------------------------------------------- 1 | 'bcrypt', 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Bcrypt Options 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may specify the configuration options that should be used when 26 | | passwords are hashed using the Bcrypt algorithm. This will allow you 27 | | to control the amount of time it takes to hash the given password. 28 | | 29 | */ 30 | 31 | 'bcrypt' => [ 32 | 'rounds' => env('BCRYPT_ROUNDS', 10), 33 | ], 34 | 35 | /* 36 | |-------------------------------------------------------------------------- 37 | | Argon Options 38 | |-------------------------------------------------------------------------- 39 | | 40 | | Here you may specify the configuration options that should be used when 41 | | passwords are hashed using the Argon algorithm. These will allow you 42 | | to control the amount of time it takes to hash the given password. 43 | | 44 | */ 45 | 46 | 'argon' => [ 47 | 'memory' => 65536, 48 | 'threads' => 1, 49 | 'time' => 4, 50 | ], 51 | 52 | ]; 53 | -------------------------------------------------------------------------------- /posts-microservice/bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /users-microservice/bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /imports-microservice/bootstrap/app.php: -------------------------------------------------------------------------------- 1 | singleton( 30 | Illuminate\Contracts\Http\Kernel::class, 31 | App\Http\Kernel::class 32 | ); 33 | 34 | $app->singleton( 35 | Illuminate\Contracts\Console\Kernel::class, 36 | App\Console\Kernel::class 37 | ); 38 | 39 | $app->singleton( 40 | Illuminate\Contracts\Debug\ExceptionHandler::class, 41 | App\Exceptions\Handler::class 42 | ); 43 | 44 | /* 45 | |-------------------------------------------------------------------------- 46 | | Return The Application 47 | |-------------------------------------------------------------------------- 48 | | 49 | | This script returns the application instance. The instance is given to 50 | | the calling script so we can separate the building of the instances 51 | | from the actual running of the application and sending responses. 52 | | 53 | */ 54 | 55 | return $app; 56 | -------------------------------------------------------------------------------- /posts-microservice/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | posts-microservice: 4 | container_name: posts-microservice 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | environment: 9 | DB_HOST: posts-microservice_db 10 | DB_DATABASE: posts-microservice 11 | DB_USERNAME: root 12 | DB_PASSWORD: root 13 | command: 'php artisan serve --host=0.0.0.0' 14 | networks: 15 | - posts-microservice 16 | - users-microservice 17 | - imports-microservice 18 | volumes: 19 | - .:/app 20 | ports: 21 | - 8082:8000 22 | depends_on: 23 | - posts-microservice_db 24 | 25 | post-microservice_queue: 26 | build: . 27 | command: 'php artisan queue:work' 28 | restart: unless-stopped 29 | environment: 30 | CACHE_DRIVER: file 31 | depends_on: 32 | - posts-microservice_db 33 | networks: 34 | - posts-microservice 35 | 36 | posts-microservice_db: 37 | platform: linux/x86_64 38 | image: mysql:5.7 39 | restart: always 40 | environment: 41 | MYSQL_DATABASE: posts-microservice 42 | # MYSQL_USER: root 43 | MYSQL_PASSWORD: root 44 | MYSQL_ROOT_PASSWORD: root 45 | networks: 46 | - posts-microservice 47 | volumes: 48 | - db-data:/var/lib/mysql 49 | ports: 50 | - 33071:3306 51 | 52 | networks: 53 | posts-microservice: 54 | name: posts-microservice 55 | users-microservice: 56 | external: 57 | name: users-microservice 58 | imports-microservice: 59 | external: 60 | name: imports-microservice 61 | volumes: 62 | db-data: 63 | -------------------------------------------------------------------------------- /imports-microservice/app/Services/ImportService.php: -------------------------------------------------------------------------------- 1 | create([ 17 | 'api_url' => $data['api_url'], 18 | 'frequency' => $data['frequency'], 19 | 'next_execution_time' => $this->setExecutionTime($data['frequency']) 20 | ]); 21 | } 22 | 23 | // Get all the imports whose next_execution_time is less than or equal to the current time 24 | public function getImportsToExecute() : array|Collection 25 | { 26 | return Import::query()->where('next_execution_time', '<=', now())->get(); 27 | } 28 | 29 | // Get all the imports 30 | public function getAllImports() : array|Collection 31 | { 32 | return Import::query()->get(); 33 | } 34 | 35 | // update import next execution time 36 | public function updateNextExecutionTime(string $importId): void 37 | { 38 | $import = Import::query()->find($importId); 39 | $nextExecutionTime = CarbonImmutable::now() 40 | ->addSeconds($import->frequency) 41 | ->format('Y-m-d H:i:s'); 42 | $import->update([ 43 | 'next_execution_time' => $nextExecutionTime 44 | ]); 45 | } 46 | 47 | // set execution time using import frequency 48 | public function setExecutionTime(int $frequency): string 49 | { 50 | return CarbonImmutable::now() 51 | ->addSeconds($frequency) 52 | ->format('Y-m-d H:i:s'); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /posts-microservice/artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 34 | 35 | $status = $kernel->handle( 36 | $input = new Symfony\Component\Console\Input\ArgvInput, 37 | new Symfony\Component\Console\Output\ConsoleOutput 38 | ); 39 | 40 | /* 41 | |-------------------------------------------------------------------------- 42 | | Shutdown The Application 43 | |-------------------------------------------------------------------------- 44 | | 45 | | Once Artisan has finished running, we will fire off the shutdown events 46 | | so that any final work may be done by the application before we shut 47 | | down the process. This is the last thing to happen to the request. 48 | | 49 | */ 50 | 51 | $kernel->terminate($input, $status); 52 | 53 | exit($status); 54 | -------------------------------------------------------------------------------- /users-microservice/artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 34 | 35 | $status = $kernel->handle( 36 | $input = new Symfony\Component\Console\Input\ArgvInput, 37 | new Symfony\Component\Console\Output\ConsoleOutput 38 | ); 39 | 40 | /* 41 | |-------------------------------------------------------------------------- 42 | | Shutdown The Application 43 | |-------------------------------------------------------------------------- 44 | | 45 | | Once Artisan has finished running, we will fire off the shutdown events 46 | | so that any final work may be done by the application before we shut 47 | | down the process. This is the last thing to happen to the request. 48 | | 49 | */ 50 | 51 | $kernel->terminate($input, $status); 52 | 53 | exit($status); 54 | -------------------------------------------------------------------------------- /imports-microservice/artisan: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | make(Illuminate\Contracts\Console\Kernel::class); 34 | 35 | $status = $kernel->handle( 36 | $input = new Symfony\Component\Console\Input\ArgvInput, 37 | new Symfony\Component\Console\Output\ConsoleOutput 38 | ); 39 | 40 | /* 41 | |-------------------------------------------------------------------------- 42 | | Shutdown The Application 43 | |-------------------------------------------------------------------------- 44 | | 45 | | Once Artisan has finished running, we will fire off the shutdown events 46 | | so that any final work may be done by the application before we shut 47 | | down the process. This is the last thing to happen to the request. 48 | | 49 | */ 50 | 51 | $kernel->terminate($input, $status); 52 | 53 | exit($status); 54 | -------------------------------------------------------------------------------- /imports-microservice/public/index.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class); 50 | 51 | $response = $kernel->handle( 52 | $request = Request::capture() 53 | )->send(); 54 | 55 | $kernel->terminate($request, $response); 56 | -------------------------------------------------------------------------------- /posts-microservice/public/index.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class); 50 | 51 | $response = $kernel->handle( 52 | $request = Request::capture() 53 | )->send(); 54 | 55 | $kernel->terminate($request, $response); 56 | -------------------------------------------------------------------------------- /users-microservice/public/index.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class); 50 | 51 | $response = $kernel->handle( 52 | $request = Request::capture() 53 | )->send(); 54 | 55 | $kernel->terminate($request, $response); 56 | -------------------------------------------------------------------------------- /users-microservice/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/laravel", 3 | "type": "project", 4 | "description": "The Laravel Framework.", 5 | "keywords": ["framework", "laravel"], 6 | "license": "MIT", 7 | "require": { 8 | "php": "^8.0.2", 9 | "guzzlehttp/guzzle": "^7.2", 10 | "laravel/framework": "^9.11", 11 | "laravel/sanctum": "^2.14.1", 12 | "laravel/tinker": "^2.7" 13 | }, 14 | "require-dev": { 15 | "fakerphp/faker": "^1.9.1", 16 | "laravel/sail": "^1.0.1", 17 | "mockery/mockery": "^1.4.4", 18 | "nunomaduro/collision": "^6.1", 19 | "phpunit/phpunit": "^9.5.10", 20 | "spatie/laravel-ignition": "^1.0" 21 | }, 22 | "autoload": { 23 | "psr-4": { 24 | "App\\": "app/", 25 | "Database\\Factories\\": "database/factories/", 26 | "Database\\Seeders\\": "database/seeders/" 27 | } 28 | }, 29 | "autoload-dev": { 30 | "psr-4": { 31 | "Tests\\": "tests/" 32 | } 33 | }, 34 | "scripts": { 35 | "post-autoload-dump": [ 36 | "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", 37 | "@php artisan package:discover --ansi" 38 | ], 39 | "post-update-cmd": [ 40 | "@php artisan vendor:publish --tag=laravel-assets --ansi --force" 41 | ], 42 | "post-root-package-install": [ 43 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 44 | ], 45 | "post-create-project-cmd": [ 46 | "@php artisan key:generate --ansi" 47 | ] 48 | }, 49 | "extra": { 50 | "laravel": { 51 | "dont-discover": [] 52 | } 53 | }, 54 | "config": { 55 | "optimize-autoloader": true, 56 | "preferred-install": "dist", 57 | "sort-packages": true 58 | }, 59 | "minimum-stability": "dev", 60 | "prefer-stable": true 61 | } 62 | -------------------------------------------------------------------------------- /posts-microservice/app/Http/Controllers/Api/AuthController.php: -------------------------------------------------------------------------------- 1 | userService = $userService; 18 | } 19 | 20 | public function register(Request $request) 21 | { 22 | try { 23 | return $this->userService->post("register", $request->all()); 24 | } 25 | catch (\Exception $e) { 26 | return response([ 27 | 'message' => json_decode($e->getMessage()) 28 | ], Response::HTTP_BAD_REQUEST); 29 | } 30 | } 31 | 32 | public function login(Request $request) 33 | { 34 | try { 35 | $response = $this->userService->post("login", $request->all()); 36 | 37 | $cookie = cookie('jwt', $response['data']['accessToken'], 60 * 24); // 1 day 38 | 39 | return response([ 40 | 'message' => 'User logged in successfully, cookie set.' 41 | ])->withCookie($cookie); 42 | } catch (\Exception $e) { 43 | return response([ 44 | 'message' => json_decode($e->getMessage()) 45 | ], Response::HTTP_BAD_REQUEST); 46 | } 47 | } 48 | 49 | public function logout() 50 | { 51 | try { 52 | $cookie = \Cookie::forget('jwt'); 53 | 54 | $this->userService->post('logout', []); 55 | 56 | return response([ 57 | 'message' => 'User logged out successfully, cookie deleted.' 58 | ])->withCookie($cookie); 59 | } 60 | catch (\Exception $e) { 61 | return response()->error(json_decode($e->getMessage()), Response::HTTP_UNAUTHORIZED); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /posts-microservice/app/Services/PostService.php: -------------------------------------------------------------------------------- 1 | get('user'); 16 | return Post::query()->create([ 17 | 'title' => $data['title'], 18 | 'description' => $data['description'], 19 | 'user_id' => $user['data']['id'], 20 | 'publication_date' => $data['publication_date'], 21 | ]); 22 | } 23 | 24 | // Get single user post 25 | public function getUserPosts(string $sortBy) : array|Collection 26 | { 27 | $user = (new UserService())->get('user'); 28 | // fetch all user post and sort by publication_date 29 | return Post::query() 30 | ->where('user_id', $user['data']['id']) 31 | ->orderBy('publication_date', $sortBy) 32 | ->get(); 33 | } 34 | 35 | // Get all posts 36 | public function getPosts(string $sortBy) : array|Collection 37 | { 38 | // fetch all posts and sort by publication_date 39 | return Post::query() 40 | ->orderBy('publication_date', $sortBy) 41 | ->get(); 42 | } 43 | 44 | // Create multiple posts for admin user 45 | public function importMultiplePosts($data) 46 | { 47 | $adminUserId = (new UserService())->get('getUserAdmin')['data']['id']; 48 | 49 | // import multiple posts for admin user 50 | collect($data)->each(function ($post) use ($adminUserId) { 51 | Post::query()->create([ 52 | 'title' => $post['title'], 53 | 'description' => $post['description'], 54 | 'user_id' => $adminUserId, 55 | 'publication_date' => $post['publication_date'], 56 | ]); 57 | }); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /posts-microservice/config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'null'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Broadcast Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the broadcast connections that will be used 26 | | to broadcast events to other systems or over websockets. Samples of 27 | | each available type of connection are provided inside this array. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'pusher' => [ 34 | 'driver' => 'pusher', 35 | 'key' => env('PUSHER_APP_KEY'), 36 | 'secret' => env('PUSHER_APP_SECRET'), 37 | 'app_id' => env('PUSHER_APP_ID'), 38 | 'options' => [ 39 | 'cluster' => env('PUSHER_APP_CLUSTER'), 40 | 'useTLS' => true, 41 | ], 42 | 'client_options' => [ 43 | // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html 44 | ], 45 | ], 46 | 47 | 'ably' => [ 48 | 'driver' => 'ably', 49 | 'key' => env('ABLY_KEY'), 50 | ], 51 | 52 | 'redis' => [ 53 | 'driver' => 'redis', 54 | 'connection' => 'default', 55 | ], 56 | 57 | 'log' => [ 58 | 'driver' => 'log', 59 | ], 60 | 61 | 'null' => [ 62 | 'driver' => 'null', 63 | ], 64 | 65 | ], 66 | 67 | ]; 68 | -------------------------------------------------------------------------------- /users-microservice/config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'null'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Broadcast Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the broadcast connections that will be used 26 | | to broadcast events to other systems or over websockets. Samples of 27 | | each available type of connection are provided inside this array. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'pusher' => [ 34 | 'driver' => 'pusher', 35 | 'key' => env('PUSHER_APP_KEY'), 36 | 'secret' => env('PUSHER_APP_SECRET'), 37 | 'app_id' => env('PUSHER_APP_ID'), 38 | 'options' => [ 39 | 'cluster' => env('PUSHER_APP_CLUSTER'), 40 | 'useTLS' => true, 41 | ], 42 | 'client_options' => [ 43 | // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html 44 | ], 45 | ], 46 | 47 | 'ably' => [ 48 | 'driver' => 'ably', 49 | 'key' => env('ABLY_KEY'), 50 | ], 51 | 52 | 'redis' => [ 53 | 'driver' => 'redis', 54 | 'connection' => 'default', 55 | ], 56 | 57 | 'log' => [ 58 | 'driver' => 'log', 59 | ], 60 | 61 | 'null' => [ 62 | 'driver' => 'null', 63 | ], 64 | 65 | ], 66 | 67 | ]; 68 | -------------------------------------------------------------------------------- /imports-microservice/config/broadcasting.php: -------------------------------------------------------------------------------- 1 | env('BROADCAST_DRIVER', 'null'), 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Broadcast Connections 23 | |-------------------------------------------------------------------------- 24 | | 25 | | Here you may define all of the broadcast connections that will be used 26 | | to broadcast events to other systems or over websockets. Samples of 27 | | each available type of connection are provided inside this array. 28 | | 29 | */ 30 | 31 | 'connections' => [ 32 | 33 | 'pusher' => [ 34 | 'driver' => 'pusher', 35 | 'key' => env('PUSHER_APP_KEY'), 36 | 'secret' => env('PUSHER_APP_SECRET'), 37 | 'app_id' => env('PUSHER_APP_ID'), 38 | 'options' => [ 39 | 'cluster' => env('PUSHER_APP_CLUSTER'), 40 | 'useTLS' => true, 41 | ], 42 | 'client_options' => [ 43 | // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html 44 | ], 45 | ], 46 | 47 | 'ably' => [ 48 | 'driver' => 'ably', 49 | 'key' => env('ABLY_KEY'), 50 | ], 51 | 52 | 'redis' => [ 53 | 'driver' => 'redis', 54 | 'connection' => 'default', 55 | ], 56 | 57 | 'log' => [ 58 | 'driver' => 'log', 59 | ], 60 | 61 | 'null' => [ 62 | 'driver' => 'null', 63 | ], 64 | 65 | ], 66 | 67 | ]; 68 | -------------------------------------------------------------------------------- /posts-microservice/app/Console/Commands/AutoImportPost.php: -------------------------------------------------------------------------------- 1 | successful()) { 43 | // Loop through all imports and create a job for each 44 | collect($importsRequest->json()['data'])->each(function ($import) use (&$jobs) { 45 | $jobs[] = (new AutoImportPostJob($import)); 46 | }); 47 | 48 | // execute jobs if there are any 49 | if (count($jobs) > 0) { 50 | // dispatch batch job using Bus 51 | Bus::batch($jobs) 52 | ->then(function (Batch $batch) { 53 | // if batch is successful, print success message 54 | info('Auto import posts successful'); 55 | }) 56 | ->catch(function (Batch $batch, Throwable $e) { 57 | info("job not successful.". $e->getMessage()); 58 | }) 59 | ->allowFailures() 60 | ->name('post:autoimport') 61 | ->dispatch(); 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /posts-microservice/app/Http/Controllers/Api/PostController.php: -------------------------------------------------------------------------------- 1 | postService = $postService; 18 | } 19 | 20 | /** 21 | * Create a new Post 22 | */ 23 | public function createPost(CreatePostRequest $request) : JsonResponse 24 | { 25 | try { 26 | $post = $this->postService->createPost($request->validated()); 27 | return response()->success($post, 'Post created successfully'); 28 | } catch (\Throwable $th) { 29 | return response()->error($th->getMessage(), 'Error creating post'); 30 | } 31 | } 32 | 33 | /** 34 | * Get all User Posts 35 | */ 36 | public function getUserPosts(Request $request) : JsonResponse 37 | { 38 | $validatedData = $request->validate([ 39 | 'sortBy' => 'nullable|string|in:desc,asc', 40 | ]); 41 | 42 | try { 43 | $posts = $this->postService->getUserPosts($validatedData['sortBy'] ?? 'asc'); 44 | return PostResource::collection($posts)->response()->setStatusCode(200); 45 | } catch (\Throwable $th) { 46 | return response()->error($th->getMessage(), 'Error retrieving posts'); 47 | } 48 | } 49 | 50 | /** 51 | * Get all Posts 52 | */ 53 | public function getPosts(Request $request) : JsonResponse 54 | { 55 | $validatedData = $request->validate([ 56 | 'sortBy' => 'nullable|string|in:desc,asc', 57 | ]); 58 | 59 | try { 60 | $posts = $this->postService->getPosts($validatedData['sortBy'] ?? 'asc'); 61 | return PostResource::collection($posts)->response()->setStatusCode(200); 62 | } catch (\Throwable $th) { 63 | return response()->error($th->getMessage(), 'Error retrieving posts'); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /users-microservice/app/Http/Controllers/Api/AuthController.php: -------------------------------------------------------------------------------- 1 | create([ 19 | 'name' => $request->name, 20 | 'email' => $request->email, 21 | 'password' => Hash::make($request->password), 22 | ]); 23 | 24 | return response()->success( 25 | [ 26 | 'user' => $user 27 | ], 28 | 'User registered successfully', 29 | Response::HTTP_CREATED 30 | ); 31 | } 32 | 33 | public function login(LoginRequest $request) 34 | { 35 | // Authenticate the user via LoginRequest 36 | $request->authenticate(); 37 | 38 | 39 | if ($request->user()->is_admin) { 40 | // Create a token for the admin 41 | $token = $request->user()->createToken('accessToken', ['admin']); 42 | } else { 43 | // Create a token for the user 44 | $token = $request->user()->createToken('accessToken', ['user']); 45 | } 46 | 47 | // Return the token 48 | return response()->success( 49 | [ 50 | 'user'=> $request->user(), 51 | 'accessToken'=> $token->plainTextToken 52 | ], 53 | 'Login Successful', 54 | Response::HTTP_OK 55 | ); 56 | } 57 | 58 | public function logout(Request $request) 59 | { 60 | 61 | $request->user()->tokens()->delete(); 62 | 63 | return response()->success( 64 | [ 65 | 'message' => 'Logged out' 66 | ] 67 | ); 68 | 69 | } 70 | 71 | public function authenticate(Request $request) 72 | { 73 | if (!$request->user()) { 74 | abort(401, 'unauthorized'); 75 | } 76 | 77 | return response()->success($request->user()); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /posts-microservice/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/laravel", 3 | "type": "project", 4 | "description": "The Laravel Framework.", 5 | "keywords": ["framework", "laravel"], 6 | "license": "MIT", 7 | "require": { 8 | "php": "^8.0.2", 9 | "guzzlehttp/guzzle": "^7.2", 10 | "laravel/framework": "^9.11", 11 | "laravel/sanctum": "^2.14.1", 12 | "laravel/tinker": "^2.7", 13 | "musahmusah/square1-user-service": "dev-main", 14 | "vladimir-yuldashev/laravel-queue-rabbitmq": "^12.0" 15 | }, 16 | "require-dev": { 17 | "fakerphp/faker": "^1.9.1", 18 | "laravel/sail": "^1.0.1", 19 | "mockery/mockery": "^1.4.4", 20 | "nunomaduro/collision": "^6.1", 21 | "phpunit/phpunit": "^9.5.10", 22 | "spatie/laravel-ignition": "^1.0" 23 | }, 24 | "repositories": [ 25 | { 26 | "type": "vcs", 27 | "url": "https://github.com/MusahMusah/square1-user-service.git" 28 | } 29 | ], 30 | "autoload": { 31 | "psr-4": { 32 | "App\\": "app/", 33 | "Database\\Factories\\": "database/factories/", 34 | "Database\\Seeders\\": "database/seeders/", 35 | "Services\\": "vendor/musahmusah/square1-user-service/src/" 36 | } 37 | }, 38 | "autoload-dev": { 39 | "psr-4": { 40 | "Tests\\": "tests/" 41 | } 42 | }, 43 | "scripts": { 44 | "post-autoload-dump": [ 45 | "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", 46 | "@php artisan package:discover --ansi" 47 | ], 48 | "post-update-cmd": [ 49 | "@php artisan vendor:publish --tag=laravel-assets --ansi --force" 50 | ], 51 | "post-root-package-install": [ 52 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 53 | ], 54 | "post-create-project-cmd": [ 55 | "@php artisan key:generate --ansi" 56 | ] 57 | }, 58 | "extra": { 59 | "laravel": { 60 | "dont-discover": [] 61 | } 62 | }, 63 | "config": { 64 | "optimize-autoloader": true, 65 | "preferred-install": "dist", 66 | "sort-packages": true 67 | }, 68 | "minimum-stability": "dev", 69 | "prefer-stable": true 70 | } 71 | -------------------------------------------------------------------------------- /imports-microservice/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/laravel", 3 | "type": "project", 4 | "description": "The Laravel Framework.", 5 | "keywords": ["framework", "laravel"], 6 | "license": "MIT", 7 | "require": { 8 | "php": "^8.0.2", 9 | "guzzlehttp/guzzle": "^7.2", 10 | "laravel/framework": "^9.11", 11 | "laravel/sanctum": "^2.14.1", 12 | "laravel/tinker": "^2.7", 13 | "musahmusah/square1-user-service": "dev-main", 14 | "vladimir-yuldashev/laravel-queue-rabbitmq": "^12.0" 15 | }, 16 | "require-dev": { 17 | "fakerphp/faker": "^1.9.1", 18 | "laravel/sail": "^1.0.1", 19 | "mockery/mockery": "^1.4.4", 20 | "nunomaduro/collision": "^6.1", 21 | "phpunit/phpunit": "^9.5.10", 22 | "spatie/laravel-ignition": "^1.0" 23 | }, 24 | "repositories": [ 25 | { 26 | "type": "vcs", 27 | "url": "https://github.com/MusahMusah/square1-user-service.git" 28 | } 29 | ], 30 | "autoload": { 31 | "psr-4": { 32 | "App\\": "app/", 33 | "Database\\Factories\\": "database/factories/", 34 | "Database\\Seeders\\": "database/seeders/", 35 | "Services\\": "vendor/musahmusah/square1-user-service/src/" 36 | } 37 | }, 38 | "autoload-dev": { 39 | "psr-4": { 40 | "Tests\\": "tests/" 41 | } 42 | }, 43 | "scripts": { 44 | "post-autoload-dump": [ 45 | "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", 46 | "@php artisan package:discover --ansi" 47 | ], 48 | "post-update-cmd": [ 49 | "@php artisan vendor:publish --tag=laravel-assets --ansi --force" 50 | ], 51 | "post-root-package-install": [ 52 | "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" 53 | ], 54 | "post-create-project-cmd": [ 55 | "@php artisan key:generate --ansi" 56 | ] 57 | }, 58 | "extra": { 59 | "laravel": { 60 | "dont-discover": [] 61 | } 62 | }, 63 | "config": { 64 | "optimize-autoloader": true, 65 | "preferred-install": "dist", 66 | "sort-packages": true 67 | }, 68 | "minimum-stability": "dev", 69 | "prefer-stable": true 70 | } 71 | -------------------------------------------------------------------------------- /posts-microservice/config/sanctum.php: -------------------------------------------------------------------------------- 1 | explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( 19 | '%s%s', 20 | 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', 21 | Sanctum::currentApplicationUrlWithPort() 22 | ))), 23 | 24 | /* 25 | |-------------------------------------------------------------------------- 26 | | Sanctum Guards 27 | |-------------------------------------------------------------------------- 28 | | 29 | | This array contains the authentication guards that will be checked when 30 | | Sanctum is trying to authenticate a request. If none of these guards 31 | | are able to authenticate the request, Sanctum will use the bearer 32 | | token that's present on an incoming request for authentication. 33 | | 34 | */ 35 | 36 | 'guard' => ['web'], 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Expiration Minutes 41 | |-------------------------------------------------------------------------- 42 | | 43 | | This value controls the number of minutes until an issued token will be 44 | | considered expired. If this value is null, personal access tokens do 45 | | not expire. This won't tweak the lifetime of first-party sessions. 46 | | 47 | */ 48 | 49 | 'expiration' => null, 50 | 51 | /* 52 | |-------------------------------------------------------------------------- 53 | | Sanctum Middleware 54 | |-------------------------------------------------------------------------- 55 | | 56 | | When authenticating your first-party SPA with Sanctum you may need to 57 | | customize some of the middleware Sanctum uses while processing the 58 | | request. You may change the middleware listed below as required. 59 | | 60 | */ 61 | 62 | 'middleware' => [ 63 | 'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class, 64 | 'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class, 65 | ], 66 | 67 | ]; 68 | -------------------------------------------------------------------------------- /users-microservice/config/sanctum.php: -------------------------------------------------------------------------------- 1 | explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( 19 | '%s%s', 20 | 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', 21 | Sanctum::currentApplicationUrlWithPort() 22 | ))), 23 | 24 | /* 25 | |-------------------------------------------------------------------------- 26 | | Sanctum Guards 27 | |-------------------------------------------------------------------------- 28 | | 29 | | This array contains the authentication guards that will be checked when 30 | | Sanctum is trying to authenticate a request. If none of these guards 31 | | are able to authenticate the request, Sanctum will use the bearer 32 | | token that's present on an incoming request for authentication. 33 | | 34 | */ 35 | 36 | 'guard' => ['web'], 37 | 38 | /* 39 | |-------------------------------------------------------------------------- 40 | | Expiration Minutes 41 | |-------------------------------------------------------------------------- 42 | | 43 | | This value controls the number of minutes until an issued token will be 44 | | considered expired. If this value is null, personal access tokens do 45 | | not expire. This won't tweak the lifetime of first-party sessions. 46 | | 47 | */ 48 | 49 | 'expiration' => null, 50 | 51 | /* 52 | |-------------------------------------------------------------------------- 53 | | Sanctum Middleware 54 | |-------------------------------------------------------------------------- 55 | | 56 | | When authenticating your first-party SPA with Sanctum you may need to 57 | | customize some of the middleware Sanctum uses while processing the 58 | | request. You may change the middleware listed below as required. 59 | | 60 | */ 61 | 62 | 'middleware' => [ 63 | 'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class, 64 | 'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class, 65 | ], 66 | 67 | ]; 68 | --------------------------------------------------------------------------------