Skip to content

Commit

Permalink
Merge branch 'main' into 157a6-email-spam-security
Browse files Browse the repository at this point in the history
  • Loading branch information
chiragchhatrala authored Dec 17, 2024
2 parents 9260b4b + 28019fc commit e9ec340
Show file tree
Hide file tree
Showing 12 changed files with 388 additions and 7 deletions.
13 changes: 13 additions & 0 deletions api/app/Http/Controllers/Forms/FormController.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use App\Http\Resources\FormResource;
use App\Models\Forms\Form;
use App\Models\Workspace;
use App\Notifications\Forms\MobileEditorEmail;
use App\Service\Forms\FormCleaner;
use App\Service\Storage\StorageFileNameParser;
use Illuminate\Support\Facades\Auth;
Expand Down Expand Up @@ -271,4 +272,16 @@ public function updateWorkspace($id, $workspace_id)
'message' => 'Form workspace updated successfully.',
]);
}

public function mobileEditorEmail($id)
{
$form = Form::findOrFail($id);
$this->authorize('update', $form);

$form->creator->notify(new MobileEditorEmail($form->slug));

return $this->success([
'message' => 'Email sent.',
]);
}
}
53 changes: 53 additions & 0 deletions api/app/Notifications/Forms/MobileEditorEmail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace App\Notifications\Forms;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class MobileEditorEmail extends Notification implements ShouldQueue
{
use Queueable;

protected $slug;

/**
* Create a new notification instance.
*
* @param string $slug
* @return void
*/
public function __construct($slug)
{
$this->slug = $slug;
}

/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}

/**
* Get the mail representation of the notification.
*
* @param mixed $notifiable
* @return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage())
->subject('Continue editing your form on desktop')
->line('We noticed you\'re editing a form on smaller screen.')
->line('For the best form building experience, we recommend using a desktop computer.')
->line('Ready to create something amazing? Click below to continue editing. 💻')
->action(__('Continue Editing'), front_url('forms/' . $this->slug . '/edit'));
}
}
28 changes: 28 additions & 0 deletions api/app/Rules/FormPropertyLogicRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@ class FormPropertyLogicRule implements DataAwareRule, ValidationRule
'content_length_less_than_or_equal_to' => [
'expected_type' => 'number',
],
'matches_regex' => [
'expected_type' => 'string',
'format' => [
'type' => 'regex'
]
],
'does_not_match_regex' => [
'expected_type' => 'string',
'format' => [
'type' => 'regex'
]
],
],
],
'matrix' => [
Expand Down Expand Up @@ -672,6 +684,8 @@ class FormPropertyLogicRule implements DataAwareRule, ValidationRule

private $data = [];

private $operator = '';

private function checkBaseCondition($condition)
{

Expand Down Expand Up @@ -712,6 +726,7 @@ private function checkBaseCondition($condition)

$typeField = $condition['value']['property_meta']['type'];
$operator = $condition['value']['operator'];
$this->operator = $operator;
$value = $condition['value']['value'];

if (!isset(self::CONDITION_MAPPING[$typeField])) {
Expand Down Expand Up @@ -750,6 +765,19 @@ private function checkBaseCondition($condition)

private function valueHasCorrectType($type, $value)
{
if ($type === 'string' && isset(self::CONDITION_MAPPING[$this->field['type']]['comparators'][$this->operator]['format'])) {
$format = self::CONDITION_MAPPING[$this->field['type']]['comparators'][$this->operator]['format'];
if ($format['type'] === 'regex') {
try {
preg_match('/' . $value . '/', '');
return true;
} catch (\Exception $e) {
$this->conditionErrors[] = 'invalid regex pattern';
return false;
}
}
}

if (
($type === 'string' && gettype($value) !== 'string') ||
($type === 'boolean' && !is_bool($value)) ||
Expand Down
13 changes: 13 additions & 0 deletions api/app/Service/Forms/FormLogicConditionChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,19 @@ private function textConditionMet(array $propertyCondition, $value): bool
return $this->checkLength($propertyCondition, $value, '<');
case 'content_length_less_than_or_equal_to':
return $this->checkLength($propertyCondition, $value, '<=');
case 'matches_regex':
try {
return (bool) preg_match('/' . $propertyCondition['value'] . '/', $value);
} catch (\Exception $e) {
ray('matches_regex_error', $e);
return false;
}
case 'does_not_match_regex':
try {
return !(bool) preg_match('/' . $propertyCondition['value'] . '/', $value);
} catch (\Exception $e) {
return true;
}
}

return false;
Expand Down
40 changes: 40 additions & 0 deletions api/resources/data/open_filters.json
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,46 @@
},
"content_length_less_than_or_equal_to": {
"expected_type": "number"
},
"matches_regex": {
"expected_type": "string",
"format": {
"type": "regex"
}
},
"does_not_match_regex": {
"expected_type": "string",
"format": {
"type": "regex"
}
}
}
},
"matrix": {
"comparators": {
"equals": {
"expected_type": "object",
"format": {
"type": "object"
}
},
"does_not_equal": {
"expected_type": "object",
"format": {
"type":"object"
}
},
"contains": {
"expected_type": "object",
"format": {
"type":"object"
}
},
"does_not_contain": {
"expected_type": "object",
"format": {
"type":"object"
}
}
}
},
Expand Down
1 change: 1 addition & 0 deletions api/routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
Route::post('/{id}/workspace/{workspace_id}', [FormController::class, 'updateWorkspace'])->name('workspace.update');
Route::put('/{id}', [FormController::class, 'update'])->name('update');
Route::delete('/{id}', [FormController::class, 'destroy'])->name('destroy');
Route::get('/{id}/mobile-editor-email', [FormController::class, 'mobileEditorEmail'])->name('mobile-editor-email');

Route::get('/{id}/submissions', [FormSubmissionController::class, 'submissions'])->name('submissions');
Route::put('/{id}/submissions/{submission_id}', [FormSubmissionController::class, 'update'])->name('submissions.update')->middleware([ResolveFormMiddleware::class]);
Expand Down
Loading

0 comments on commit e9ec340

Please sign in to comment.