diff --git a/app/Library/Poowf/Unicorn.php b/app/Library/Poowf/Unicorn.php index 707cef18..72badcda 100644 --- a/app/Library/Poowf/Unicorn.php +++ b/app/Library/Poowf/Unicorn.php @@ -4,6 +4,7 @@ use App\Models\Role; use Carbon\Carbon; +use DOMDocument; use GuzzleHttp\Client; use Illuminate\Support\Str; use Parsedown; @@ -354,4 +355,29 @@ public static function redirectTo() return $url; } + + public static function stripUnwantedTagsAndAttrs($html_str){ + $xml = new DOMDocument(); + //Suppress warnings: proper error handling is beyond scope of example + libxml_use_internal_errors(true); + //List the tags you want to allow here, NOTE you MUST allow html and body otherwise entire string will be cleared + $allowed_tags = array("html", "body", "b", "strong", "sup", "sub", "h1", "h2", "h3", "h4", "blockquote", "br", "em", "del", "hr", "i", "li", "ol", "p", "s", "span", "table", "tr", "td", "u", "ul", "a", "img"); + //List the attributes you want to allow here + $allowed_attrs = array ("class", "id", "style", "href", "title", "target", "alt"); + if (!strlen($html_str)){return false;} + if ($xml->loadHTML($html_str, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD)){ + foreach ($xml->getElementsByTagName("*") as $tag){ + if (!in_array($tag->tagName, $allowed_tags)){ + $tag->parentNode->removeChild($tag); + } else { + foreach ($tag->attributes as $attr){ + if (!in_array($attr->nodeName, $allowed_attrs)){ + $tag->removeAttribute($attr->nodeName); + } + } + } + } + } + return $xml->saveHTML(); + } } diff --git a/app/Models/CompanySetting.php b/app/Models/CompanySetting.php index fa109e4d..5eb46a7d 100644 --- a/app/Models/CompanySetting.php +++ b/app/Models/CompanySetting.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Library\Poowf\Unicorn; use Dyrynda\Database\Support\CascadeSoftDeletes; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -36,6 +37,16 @@ class CompanySetting extends Model implements Auditable 'tax' => 0, ]; + public function setInvoiceConditionsAttribute($description) + { + $this->attributes['invoice_conditions'] = Unicorn::stripUnwantedTagsAndAttrs($description, ENT_COMPAT, 'UTF-8'); + } + + public function setQuoteConditionsAttribute($description) + { + $this->attributes['quote_conditions'] = Unicorn::stripUnwantedTagsAndAttrs($description, ENT_COMPAT, 'UTF-8'); + } + protected static function boot() { parent::boot(); diff --git a/app/Models/InvoiceItem.php b/app/Models/InvoiceItem.php index 644681a8..e97b7412 100644 --- a/app/Models/InvoiceItem.php +++ b/app/Models/InvoiceItem.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Library\Poowf\Unicorn; use Dyrynda\Database\Support\CascadeSoftDeletes; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -20,6 +21,11 @@ class InvoiceItem extends Model implements Auditable */ protected $table = 'invoice_items'; + public function setDescriptionAttribute($description) + { + $this->attributes['description'] = Unicorn::stripUnwantedTagsAndAttrs($description, ENT_COMPAT, 'UTF-8'); + } + public function invoice() { return $this->belongsTo('App\Models\Invoice', 'invoice_id'); diff --git a/app/Models/InvoiceItemTemplate.php b/app/Models/InvoiceItemTemplate.php index d4b1c0b3..fcf98011 100644 --- a/app/Models/InvoiceItemTemplate.php +++ b/app/Models/InvoiceItemTemplate.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Library\Poowf\Unicorn; use Dyrynda\Database\Support\CascadeSoftDeletes; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -32,6 +33,11 @@ class InvoiceItemTemplate extends Model implements Auditable 'description', ]; + public function setDescriptionAttribute($description) + { + $this->attributes['description'] = Unicorn::stripUnwantedTagsAndAttrs($description, ENT_COMPAT, 'UTF-8'); + } + public function template() { return $this->belongsTo('App\Models\InvoiceTemplate', 'invoice_template_id'); diff --git a/app/Models/ItemTemplate.php b/app/Models/ItemTemplate.php index e35058ef..4c1acea1 100644 --- a/app/Models/ItemTemplate.php +++ b/app/Models/ItemTemplate.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Library\Poowf\Unicorn; use Dyrynda\Database\Support\CascadeSoftDeletes; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -27,6 +28,11 @@ class ItemTemplate extends Model implements Auditable 'description', ]; + public function setDescriptionAttribute($description) + { + $this->attributes['description'] = Unicorn::stripUnwantedTagsAndAttrs($description, ENT_COMPAT, 'UTF-8'); + } + public function duplicate() { $cloned = $this->replicate(); diff --git a/app/Models/QuoteItem.php b/app/Models/QuoteItem.php index 5668d081..36c6c08d 100644 --- a/app/Models/QuoteItem.php +++ b/app/Models/QuoteItem.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Library\Poowf\Unicorn; use Dyrynda\Database\Support\CascadeSoftDeletes; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; @@ -20,6 +21,11 @@ class QuoteItem extends Model implements Auditable */ protected $table = 'quote_items'; + public function setDescriptionAttribute($description) + { + $this->attributes['description'] = Unicorn::stripUnwantedTagsAndAttrs($description, ENT_COMPAT, 'UTF-8'); + } + public function quote() { return $this->belongsTo('App\Models\Quote', 'quote_id');