2023-12-14 16:40:43 +01:00
< ? php
/**
* Invoice Ninja ( https :// invoiceninja . com ) .
*
* @ link https :// github . com / invoiceninja / invoiceninja source repository
*
* @ copyright Copyright ( c ) 2023. Invoice Ninja LLC ( https :// invoiceninja . com )
*
* @ license https :// www . elastic . co / licensing / elastic - license
*/
namespace App\Http\Controllers ;
use App\Jobs\Mailgun\ProcessMailgunInboundWebhook ;
2023-12-14 19:17:29 +01:00
use App\Jobs\Mailgun\ProcessMailgunWebhook ;
2023-12-14 16:40:43 +01:00
use Illuminate\Http\Request ;
2024-03-18 08:04:54 +01:00
use Log ;
2023-12-14 16:40:43 +01:00
/**
2023-12-14 19:17:29 +01:00
* Class MailgunController .
2023-12-14 16:40:43 +01:00
*/
class MailgunController extends BaseController
{
private $invitation ;
public function __construct ()
{
}
/**
2023-12-14 19:17:29 +01:00
* Process Mailgun Webhook .
2023-12-14 16:40:43 +01:00
*
*
* @ OA\Post (
2023-12-14 19:17:29 +01:00
* path = " /api/v1/mailgun_webhook " ,
* operationId = " mailgunWebhook " ,
* tags = { " mailgun " },
* summary = " Processing webhooks from Mailgun " ,
* description = " Adds an credit to the system " ,
* @ OA\Parameter ( ref = " #/components/parameters/X-API-TOKEN " ),
* @ OA\Parameter ( ref = " #/components/parameters/X-Requested-With " ),
* @ OA\Parameter ( ref = " #/components/parameters/include " ),
* @ OA\Response (
* response = 200 ,
* description = " Returns the saved credit object " ,
* @ OA\Header ( header = " X-MINIMUM-CLIENT-VERSION " , ref = " #/components/headers/X-MINIMUM-CLIENT-VERSION " ),
* @ OA\Header ( header = " X-RateLimit-Remaining " , ref = " #/components/headers/X-RateLimit-Remaining " ),
* @ OA\Header ( header = " X-RateLimit-Limit " , ref = " #/components/headers/X-RateLimit-Limit " ),
* @ OA\JsonContent ( ref = " #/components/schemas/Credit " ),
* ),
* @ OA\Response (
* response = 422 ,
* description = " Validation error " ,
* @ OA\JsonContent ( ref = " #/components/schemas/ValidationError " ),
*
* ),
* @ OA\Response (
* response = " default " ,
* description = " Unexpected Error " ,
* @ OA\JsonContent ( ref = " #/components/schemas/Error " ),
* ),
* )
*/
public function webhook ( Request $request )
{
2024-01-20 08:53:47 +01:00
$input = $request -> all ();
2024-02-27 08:13:19 +01:00
if ( \abs ( \time () - $request [ 'signature' ][ 'timestamp' ]) > 15 ) {
2023-12-14 19:17:29 +01:00
return response () -> json ([ 'message' => 'Success' ], 200 );
2024-02-27 08:13:19 +01:00
}
2023-12-14 19:17:29 +01:00
2024-02-27 08:13:19 +01:00
if ( \hash_equals ( \hash_hmac ( 'sha256' , $input [ 'signature' ][ 'timestamp' ] . $input [ 'signature' ][ 'token' ], config ( 'services.mailgun.webhook_signing_key' )), $input [ 'signature' ][ 'signature' ])) {
2024-01-20 08:53:47 +01:00
ProcessMailgunWebhook :: dispatch ( $request -> all ()) -> delay ( 10 );
2024-02-27 08:13:19 +01:00
}
2024-01-20 08:53:47 +01:00
return response () -> json ([ 'message' => 'Success.' ], 200 );
2023-12-14 19:17:29 +01:00
}
/**
* Process Mailgun Webhook .
*
*
* @ OA\Post (
* path = " /api/v1/mailgun_inbound_webhook " ,
* operationId = " mailgunInboundWebhook " ,
* tags = { " mailgun " },
* summary = " Processing inbound webhooks from Mailgun " ,
2023-12-14 16:40:43 +01:00
* description = " Adds an credit to the system " ,
* @ OA\Parameter ( ref = " #/components/parameters/X-API-TOKEN " ),
* @ OA\Parameter ( ref = " #/components/parameters/X-Requested-With " ),
* @ OA\Parameter ( ref = " #/components/parameters/include " ),
* @ OA\Response (
* response = 200 ,
* description = " Returns the saved credit object " ,
* @ OA\Header ( header = " X-MINIMUM-CLIENT-VERSION " , ref = " #/components/headers/X-MINIMUM-CLIENT-VERSION " ),
* @ OA\Header ( header = " X-RateLimit-Remaining " , ref = " #/components/headers/X-RateLimit-Remaining " ),
* @ OA\Header ( header = " X-RateLimit-Limit " , ref = " #/components/headers/X-RateLimit-Limit " ),
* @ OA\JsonContent ( ref = " #/components/schemas/Credit " ),
* ),
* @ OA\Response (
* response = 422 ,
* description = " Validation error " ,
* @ OA\JsonContent ( ref = " #/components/schemas/ValidationError " ),
*
* ),
* @ OA\Response (
* response = " default " ,
* description = " Unexpected Error " ,
* @ OA\JsonContent ( ref = " #/components/schemas/Error " ),
* ),
* )
*/
2024-01-20 08:53:47 +01:00
public function inboundWebhook ( Request $request )
2023-12-14 16:40:43 +01:00
{
2024-03-18 08:04:54 +01:00
$input = $request -> all ();
2023-12-14 16:40:43 +01:00
2024-03-19 12:56:39 +01:00
if ( ! array_key_exists ( 'recipient' , $input ) || ! array_key_exists ( 'message-url' , $input )) {
Log :: info ( 'Failed: Message could not be parsed, because required parameters are missing. Please ensure contacting this api-endpoint with a store & notify operation instead of a forward operation!' );
2024-03-19 13:09:03 +01:00
return response () -> json ([ 'message' => 'Failed. Missing Parameters. Use store and notify!' ], 400 );
2024-03-19 12:56:39 +01:00
}
2024-03-18 08:04:54 +01:00
if ( ! array_key_exists ( 'attachments' , $input ) || count ( json_decode ( $input [ 'attachments' ])) == 0 ) {
2024-03-19 12:56:39 +01:00
Log :: info ( 'Message ignored because of missing attachments. No Actions would have been taken...' );
2024-03-18 08:04:54 +01:00
return response () -> json ([ 'message' => 'Sucess. Soft Fail. Missing Attachments.' ], 200 );
}
2024-03-19 12:56:39 +01:00
if ( \abs ( \time () - ( int ) $input [ 'timestamp' ]) > 150 ) {
2024-03-18 08:04:54 +01:00
Log :: info ( 'Message ignored because of request body is too old.' );
return response () -> json ([ 'message' => 'Success. Soft Fail. Message too old.' ], 200 );
}
2024-03-19 08:10:18 +01:00
// @turbo124 TODO: how to check for services.mailgun.webhook_signing_key on company level, when custom credentials are defined
2024-03-18 08:04:54 +01:00
if ( \hash_equals ( \hash_hmac ( 'sha256' , $input [ 'timestamp' ] . $input [ 'token' ], config ( 'services.mailgun.webhook_signing_key' )), $input [ 'signature' ])) {
2024-03-19 12:56:39 +01:00
ProcessMailgunInboundWebhook :: dispatch ( $input [ " recipient " ] . " | " . $input [ " message-url " ]) -> delay ( 10 );
2024-03-18 08:04:54 +01:00
return response () -> json ([ 'message' => 'Success' ], 201 );
2024-01-20 08:53:47 +01:00
}
2023-12-14 16:40:43 +01:00
2024-01-20 08:53:47 +01:00
return response () -> json ([ 'message' => 'Unauthorized' ], 403 );
2023-12-14 16:40:43 +01:00
}
}