Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 89
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
AI
0.00% covered (danger)
0.00%
0 / 89
0.00% covered (danger)
0.00%
0 / 5
506
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 send_email
0.00% covered (danger)
0.00%
0 / 73
0.00% covered (danger)
0.00%
0 / 1
182
 isEmailValid
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 isValidHtml
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 isValidEmailSubject
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
30
1<?php
2
3namespace App\Http\Controllers;
4
5use Illuminate\Support\Facades\Validator;
6use Illuminate\Http\Request;
7
8class AI extends Controller
9{
10    public function __construct(){
11
12    }
13
14    public function send_email(Request $request){
15
16        try {
17            
18            $data = $request->all();
19
20            $body = "";
21            $subject = "";
22
23            $validator = Validator::make($data, [
24                'email' => ['required', 'email'],
25                'subject' => ['required'],
26                'body' => ['required'],
27            ]);        
28
29            if ($validator->fails()) {
30                if ($validator->errors()->has('email')
31                    && !$request->has('email')) {
32
33                    return response()->json([
34                        'status'  => 'error',
35                        'message' => 'Missing required field: email',
36                        'code'    => 'MISSING_FIELD',
37                    ], 400);
38                }
39
40                if (!$this->isEmailValid($data['email'])) {
41                    return response([
42                        'status'  => 'error',
43                        'message' => 'Invalid email address format!',
44                        'code'    => 'INVALID_EMAIL',
45                    ], 400);
46                }
47
48                if ($validator->errors()->has('subject')
49                    && !$request->has('subject')) {
50
51                    return response()->json([
52                        'status'  => 'error',
53                        'message' => 'Missing required field: subject',
54                        'code'    => 'MISSING_FIELD',
55                    ], 400);
56                }
57
58                if(!$this->isValidEmailSubject($data['subject'])){
59                    return response([
60                        'status'  => 'error',
61                        'message' => 'Invalid email subject!',
62                        'code'    => 'INVALID_SUBJECT',
63                    ], 400);
64                }
65
66                if ($validator->errors()->has('body')
67                    && !$request->has('body')) {
68
69                    return response()->json([
70                        'status'  => 'error',
71                        'message' => 'Missing required field: body',
72                        'code'    => 'MISSING_FIELD',
73                    ], 400);
74                }
75
76                if (!$this->isValidHtml($data['body'])) {
77                    return response()->json([
78                        'status'  => 'error',
79                        'message' => 'Invalid HTML!',
80                        'code'    => 'INVALID_BODY',
81                    ], 422);
82                }
83            }
84
85            $toEmail = $data['email'];
86            $body = $data['body'];
87            $subject = $data['subject'];            
88
89            $mail = new \SendGrid\Mail\Mail();                     
90
91            $mail->setFrom('fire@fire.es', 'Fire Service Titan');            
92            $mail->addTo($toEmail);
93            $mail->setSubject($subject);
94            $mail->addContent("text/html", $body);
95            
96            $sendgrid = new \SendGrid(env('SENDGRID_API_KEY','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'));
97
98            $response = $sendgrid->send($mail);
99            if ($response->statusCode() == 202) {
100                return response([
101                    'status'  => 'success',
102                    'message' => 'Verification email sent successfully!',
103                    'email'   => $toEmail,
104                ], 200);
105            }            
106
107            return response([
108                'status'  => 'error',
109                'message' => 'Failed to send email. Please try again later.',
110                'code'    => 'EMAIL_DELIVERY_FAILED',
111            ], 500);
112
113        } catch (\Exception $e) {
114            /** @disregard P1014 */
115            $e->exceptionCode = 'SEND_VERIFICATION_EMAIL_EXCEPTION'; 
116            report($e);
117            return response(['message' => 'KO', 'error' => $e->getMessage()]);
118        }
119
120    }    
121
122    function isEmailValid($email) {
123        
124        $pattern = '/^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$/';
125        
126        if (preg_match($pattern, $email)) {
127            return true;
128        } else {
129            return false;
130        }
131
132    }
133
134
135    private function isValidHtml($html)
136    {
137        libxml_use_internal_errors(true);
138
139        $dom = new \DOMDocument();
140        $isValid = $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
141
142        libxml_clear_errors();
143
144        return $isValid;
145    }
146
147    function isValidEmailSubject(string $subject): bool
148    {        
149        $subject = trim($subject);
150        
151        if ($subject === '' || mb_strlen($subject) < 3 || mb_strlen($subject) > 150) {
152            return false;
153        }
154        
155        if (preg_match('/[\r\n]/', $subject)) {
156            return false;
157        }
158
159        return true;
160    }
161}