Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fa005 submissions file link in notifications #298

Merged
merged 5 commits into from
Jan 31, 2024

Conversation

madassdev
Copy link
Collaborator

@madassdev madassdev commented Jan 30, 2024

Summary by CodeRabbit

  • New Features
    • Enhanced form submission emails to include structured information about attached files, providing direct links and labels for easier access.
  • Refactor
    • Improved handling and formatting of email data related to form submissions.
    • Refactored the PhoneInput.vue component to improve state initialization and input handling.

@madassdev madassdev requested review from JhumanJ and formsdev January 30, 2024 10:43
Copy link
Contributor

coderabbitai bot commented Jan 30, 2024

Walkthrough

The recent updates aim to enhance form submissions by improving the handling of email data, particularly for files. These changes involve the introduction of structured information about file URLs and labels in email data, as well as conditional rendering for displaying this data. The modifications are designed to enhance the presentation and accessibility of file attachments in email notifications related to form submissions.

Changes

File Path Change Summary
app/Service/Forms/FormSubmissionFormatter.php Added logic for populating email_data with file information and updated control flow for email data processing.
app/Http/Controllers/Forms/FormSubmissionController.php Modified the export method to incorporate the useSignedUrlForFiles method call.
app/Mail/Forms/SubmissionConfirmationMail.php Updated the build method to include the useSignedUrlForFiles method call in the chain.
app/Notifications/Forms/FormSubmissionNotification.php Modified the toMail method to include the useSignedUrlForFiles method call in the chain.
resources/views/mail/form/confirmation-submission-notification.blade.php Introduced conditional block to render file links or field value based on field type.
client/components/forms/PhoneInput.vue Added compVal method for state initialization and refactored state initialization logic.

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share

Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit-tests for this file.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit tests for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository from git and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 7348605 and 3231642.
Files selected for processing (3)
  • app/Service/Forms/FormSubmissionFormatter.php (1 hunks)
  • resources/views/mail/form/confirmation-submission-notification.blade.php (1 hunks)
  • resources/views/mail/form/submission-notification.blade.php (1 hunks)

Comment on lines +13 to +20
@if($field['type'] == 'files')
<br/>
@foreach($field['email_data'] as $link)
<a href="{{$link['signed_url']}}">{{$link['label']}}</a> <br/>
@endforeach
@else
{!! is_array($field['value'])?implode(',',$field['value']):$field['value']!!}

@endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation of conditional rendering based on the field type ('files') and the generation of hyperlinks for each file is correct and follows Laravel's Blade templating best practices. However, consider escaping the output of $field['name'] to prevent potential XSS vulnerabilities when displaying user-generated content.

- **{{$field['name']}}**
+ **{{ htmlspecialchars($field['name'], ENT_QUOTES, 'UTF-8') }}**

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
@if($field['type'] == 'files')
<br/>
@foreach($field['email_data'] as $link)
<a href="{{$link['signed_url']}}">{{$link['label']}}</a> <br/>
@endforeach
@else
{!! is_array($field['value'])?implode(',',$field['value']):$field['value']!!}
@endif
@if($field['type'] == 'files')
<br/>
@foreach($field['email_data'] as $link)
<a href="{{$link['signed_url']}}">{{$link['label']}}</a> <br/>
@endforeach
@else
{!! is_array($field['value'])?implode(',',$field['value']):$field['value']!!}
@endif

Comment on lines +20 to +27
@if($field['type'] == 'files')
<br/>
@foreach($field['email_data'] as $link)
<a href="{{$link['signed_url']}}">{{$link['label']}}</a> <br/>
@endforeach
@else
{!! is_array($field['value'])?implode(',',$field['value']):$field['value']!!}

@endif
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation of conditional rendering for the 'files' field type and hyperlink generation for each file in the confirmation submission notification is correct and adheres to Laravel's Blade templating best practices. As with the previous file, consider escaping the output of $field['name'] to enhance security against potential XSS vulnerabilities.

- **{{$field['name']}}**
+ **{{ htmlspecialchars($field['name'], ENT_QUOTES, 'UTF-8') }}**

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
@if($field['type'] == 'files')
<br/>
@foreach($field['email_data'] as $link)
<a href="{{$link['signed_url']}}">{{$link['label']}}</a> <br/>
@endforeach
@else
{!! is_array($field['value'])?implode(',',$field['value']):$field['value']!!}
@endif
@if($field['type'] == 'files')
<br/>
@foreach($field['email_data'] as $link)
<a href="{{$link['signed_url']}}">{{$link['label']}}</a> <br/>
@endforeach
@else
{!! is_array($field['value'])?implode(',',$field['value']):$field['value']!!}
@endif

Copy link
Owner

@JhumanJ JhumanJ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, just a tiny detail :)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 3231642 and dedc21b.
Files selected for processing (1)
  • app/Service/Forms/FormSubmissionFormatter.php (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • app/Service/Forms/FormSubmissionFormatter.php

@madassdev madassdev requested a review from JhumanJ January 30, 2024 14:33
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 3

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between dedc21b and ed4d04e.
Files selected for processing (1)
  • client/components/forms/PhoneInput.vue (4 hunks)
Additional comments: 1
client/components/forms/PhoneInput.vue (1)
  • 108-108: The call to initState within mounted is appropriate for initializing the component state based on compVal. However, ensure that initState is idempotent and can safely be called multiple times without unintended side effects.

Comment on lines 96 to 98
compVal(newVal, oldVal){
this.initState()
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The compVal watcher is correctly triggering initState upon changes. However, it lacks a specific condition to check if the change in compVal actually requires re-initialization. This could potentially lead to unnecessary calls to initState, affecting performance.

Consider adding a condition to check if compVal has a significant change that warrants the re-initialization of state.

@@ -131,6 +124,7 @@
},
onInput (event) {
this.inputVal = event?.target?.value.replace(/[^0-9]/g, '')

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The onInput method effectively sanitizes the input value by removing non-numeric characters. This is a good practice for phone number inputs. However, consider adding a comment explaining the regex used for maintainability.

Would you like a comment added to explain the regex used in onInput for future maintainability?

Comment on lines 137 to 151
initState() {
if(this.compVal === null){
return;
}
if (!this.compVal.startsWith('+')) {
this.selectedCountryCode = this.getCountryBy(this.compVal.substring(2, 0))
}

const phoneObj = parsePhoneNumber(this.compVal)
if (phoneObj !== undefined && phoneObj) {
if (!this.selectedCountryCode && phoneObj.country !== undefined && phoneObj.country) {
this.selectedCountryCode = this.getCountryBy(phoneObj.country)
}
this.inputVal = phoneObj.nationalNumber
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The initState method is well-structured and handles the initialization of the component state based on compVal. It correctly handles cases where compVal is null and parses the phone number to set the country code and national number. However, there are a few points to consider:

  • The check for compVal starting with '+' (line 141) uses a substring method incorrectly. It should use (0, 2) instead of (2, 0) to extract the first two characters.
  • The use of parsePhoneNumber assumes the existence of a valid compVal. Consider adding error handling for cases where parsePhoneNumber returns undefined or an invalid object.
- this.selectedCountryCode = this.getCountryBy(this.compVal.substring(2, 0))
+ this.selectedCountryCode = this.getCountryBy(this.compVal.substring(0, 2))

Consider adding error handling for parsePhoneNumber to ensure robustness.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
initState() {
if(this.compVal === null){
return;
}
if (!this.compVal.startsWith('+')) {
this.selectedCountryCode = this.getCountryBy(this.compVal.substring(2, 0))
}
const phoneObj = parsePhoneNumber(this.compVal)
if (phoneObj !== undefined && phoneObj) {
if (!this.selectedCountryCode && phoneObj.country !== undefined && phoneObj.country) {
this.selectedCountryCode = this.getCountryBy(phoneObj.country)
}
this.inputVal = phoneObj.nationalNumber
}
initState() {
if(this.compVal === null){
return;
}
if (!this.compVal.startsWith('+')) {
this.selectedCountryCode = this.getCountryBy(this.compVal.substring(0, 2))
}
const phoneObj = parsePhoneNumber(this.compVal)
if (phoneObj !== undefined && phoneObj) {
if (!this.selectedCountryCode && phoneObj.country !== undefined && phoneObj.country) {
this.selectedCountryCode = this.getCountryBy(phoneObj.country)
}
this.inputVal = phoneObj.nationalNumber
}

@madassdev madassdev force-pushed the fa005-submissions-file-link-in-notifications branch from ed4d04e to dedc21b Compare January 31, 2024 09:36
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between dedc21b and b2bd884.
Files selected for processing (4)
  • app/Http/Controllers/Forms/FormSubmissionController.php (1 hunks)
  • app/Mail/Forms/SubmissionConfirmationMail.php (1 hunks)
  • app/Notifications/Forms/FormSubmissionNotification.php (1 hunks)
  • app/Service/Forms/FormSubmissionFormatter.php (5 hunks)
Files skipped from review as they are similar to previous changes (1)
  • app/Service/Forms/FormSubmissionFormatter.php
Additional comments: 6
app/Mail/Forms/SubmissionConfirmationMail.php (2)
  • 38-39: The addition of ->useSignedUrlForFiles() after ->outputStringsOnly() in the build method is a logical step to ensure that file URLs in the email notifications are signed, enhancing security by making sure that only intended recipients can access the files. This change aligns with best practices for handling file access in web applications.
  • 35-42: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-57]

Overall, the SubmissionConfirmationMail class is well-structured and follows good coding practices. The use of dependency injection for the FormSubmitted event in the constructor is commendable for its maintainability and modularity. The dynamic generation of the From email address in getFromEmail and the conditional logic in getReplyToEmail are implemented correctly. However, ensure that the dynamic From email address does not conflict with SPF records, potentially leading to emails being marked as spam.

app/Http/Controllers/Forms/FormSubmissionController.php (2)
  • 40-41: The addition of ->useSignedUrlForFiles() in the export method ensures that the URLs for files in the exported data are signed. This is a crucial security measure for protecting access to files, ensuring that only authorized users can download them. It's important to verify that the signing process does not significantly impact the performance of the export functionality, especially for forms with a large number of submissions.
  • 37-44: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-63]

The FormSubmissionController is well-implemented, with clear separation of concerns and adherence to best practices. The use of middleware for authentication and signed URLs is correctly applied. The submissionFile method's handling of file retrieval and support for different storage systems (local and S3) is properly implemented. However, consider adding error handling for potential exceptions during the export process, such as issues with file system operations or Excel generation failures, to improve the robustness of the application.

app/Notifications/Forms/FormSubmissionNotification.php (2)
  • 52-53: The inclusion of ->useSignedUrlForFiles() after ->outputStringsOnly() in the toMail method is a prudent addition, ensuring that file URLs in the email notifications are signed. This enhances the security of file access from email notifications. This change is consistent with the modifications in other parts of the application, maintaining a uniform approach to handling file URLs.
  • 49-56: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-76]

The FormSubmissionNotification class is implemented following good coding practices. The dynamic generation of the From email address and the conditional logic for determining the ReplyTo email address are correctly handled. The method validateEmail for email validation is a good utility. However, ensure that the use of dynamic email addresses in getFromEmail is in compliance with email sending policies and does not affect deliverability. Additionally, the method getRespondentEmail assumes only one email field per form, which is a reasonable assumption but should be clearly documented in the form design guidelines to avoid confusion.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between b2bd884 and d307459.
Files selected for processing (1)
  • resources/views/mail/form/confirmation-submission-notification.blade.php (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • resources/views/mail/form/confirmation-submission-notification.blade.php

@JhumanJ JhumanJ merged commit 38cb133 into main Jan 31, 2024
4 checks passed
@JhumanJ JhumanJ deleted the fa005-submissions-file-link-in-notifications branch January 31, 2024 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants