
Security Fundamentals
Turtles, Clams, and Cyber Threat Actors: Shell Usage
The Socket Threat Research Team uncovers how threat actors weaponize shell techniques across npm, PyPI, and Go ecosystems to maintain persistence and exfiltrate data.
react-commentview
Advanced tools
A reusable react component to show comments or discussions on a particular topic
A responsive, reusable & customizable react component that can be used as a comment box or as a comment input. It is a pure front-end component and does not require backend coding.
![]() React |
![]() AWS Serverless |
![]() Bootstrap |
Use this flexible, customizable and reusable React component to develop user comments based functionality into your application. It is packed with functionality, keeping the basic usage simple. It is designed in Bootstrap, is responsive and renders nicely on all screen sizes. Customizable color scheme allows it to seamlessly blend in to any UI. It depends on AWS serverless technologies for certain functionalities such as uploading and processing attachments. However, it is a pure front-end component and does not need backend coding.
Possible usage of this component includes but is not limited to the following use-cases:
and many more.
This component has three operating modes - view mode, edit mode and deleted mode. For setting the mode during initial render, a prop is used. As the user interacts with the component further, the component can switch from one mode to other. This behaviour can be controlled by setting the props.
In view mode the comment text is displayed along with other enabled decorations, such as likes, votes, etc.
In edit mode, the component functions as a comment editor. Edit mode can be used for accepting new comments as well as editing existing comments. User can provide text, image, pdf and video as inputs. For uploading attachments such as images, pdfs and video, this component depends on AWS. Backend coding is not necessary. Only AWS configuration is required.
Deleted mode looks like the image below.
This component provides the following functionality:
Read this section to get started with the implementation. You can use this component in view, edit and delete modes. This section will help you get started with the basic usage. After you become familiar, you can move on to explore props, further features and customization.
Install Dependencies
This module depends on the following packages. Install them first.
npm install --save aws-sdk
npm install --save bootstrap
npm install --save react-bootstrap
npm install --save react-bootstrap-icons
npm install --save react-ui-components-superflows
npm install --save react-ui-themes-superflows
npm install --save react-upload-to-s3
AWS Configuration
Following AWS services are used by this component:
The configuration section will help you in your AWS setup.
npm install --save react-commentview
Same component can be reused in multiple ways, simply by using various combination of props. Three very basic use-cases are covered in this section.
After you become familiar with these use-cases, you can move on to studying the props and then understanding the subsequent use-cases.
As a simple editor
import React from 'react'
import { Col, Row, Container } from 'react-bootstrap';
import { CommentView } from 'react-commentview'
import Themes from 'react-ui-themes-superflows'
import 'bootstrap/dist/css/bootstrap.min.css';
const App = () => {
const theme = Themes.getTheme("Default");
return (
<Container className='mt-5'>
<Row className='justify-content-center'>
<Col sm={12} xs={12} md={6} xxl={6} >
<CommentView
bucket="your_bucket"
awsRegion="your_aws_region"
awsKey="your_aws_key"
awsSecret="your_aws_secret"
awsMediaConvertEndPoint="https://<endpoint_prefix>.mediaconvert.<region>.amazonaws.com"
mediaConvertRole="mediaconvert_role"
cdnPrefix="your_cdn_prefix"
mode="edit"
preventEditToView={true}
clearOnSubmit={true}
callbackInfo={{id: 22}}
user={{id: 2, name: "Hrushi M", picture: "https://image.shutterstock.com/mosaic_250/2780032/1714666150/stock-photo-head-shot-portrait-close-up-smiling-confident-businessman-wearing-glasses-looking-at-camera-1714666150.jpg", timestamp: "1660215594"}}
onSubmit={(result) => {console.log('submit result', result);}}
theme={theme}
onSubmit={(result) => {console.log('submit result', result);}}
/>
</Col>
</Row>
</Container>
);
}
export default App
To display a comment
import React from 'react'
import { Col, Row, Container } from 'react-bootstrap';
import { CommentView } from 'react-commentview'
import Themes from 'react-ui-themes-superflows'
import 'bootstrap/dist/css/bootstrap.min.css';
const App = () => {
const theme = Themes.getTheme("Default");
return (
<Container className='mt-5'>
<Row className='justify-content-center'>
<Col sm={12} xs={12} md={6} xxl={6} >
<CommentView
bucket="your_bucket"
awsRegion="your_aws_region"
awsKey="your_aws_key"
awsSecret="your_aws_secret"
awsMediaConvertEndPoint="https://<endpoint_prefix>.mediaconvert.<region>.amazonaws.com"
mediaConvertRole="mediaconvert_role"
cdnPrefix="your_cdn_prefix"
mode="view"
preFill={{id: 10, text: 'Hello how are you doing? Hoping that things are going good at your end. Lets catchup soon, have something to discuss!', attachment: {object: 'http://superflows.dev/234232344.mp4', type: 'video'}}}
user={{id: 2, name: "Hrushi M", picture: "https://image.shutterstock.com/mosaic_250/2780032/1714666150/stock-photo-head-shot-portrait-close-up-smiling-confident-businessman-wearing-glasses-looking-at-camera-1714666150.jpg", timestamp: "1660215594"}}
theme={theme}
onReplied={(result) => {console.log('reply result', result);}}
/>
</Col>
</Row>
</Container>
);
}
export default App
To display a deleted comment
import React from 'react'
import { Col, Row, Container } from 'react-bootstrap';
import { CommentView } from 'react-commentview'
import Themes from 'react-ui-themes-superflows'
import 'bootstrap/dist/css/bootstrap.min.css';
const App = () => {
const theme = Themes.getTheme("Default");
return (
<Container className='mt-5'>
<Row className='justify-content-center'>
<Col sm={12} xs={12} md={6} xxl={6} >
<CommentView
mode="deleted"
user={{id: 2, name: "Hrushi M", picture: "https://image.shutterstock.com/mosaic_250/2780032/1714666150/stock-photo-head-shot-portrait-close-up-smiling-confident-businessman-wearing-glasses-looking-at-camera-1714666150.jpg", timestamp: "1660215594"}}
theme={theme}
/>
</Col>
</Row>
</Container>
);
}
export default App
Use the table below to understand the props and how they can be set to customize the appearance and behaviour of this component.
Please refer to the AWS configuration section to know how to obtain your values for these props.
Prop | Type | Description |
---|---|---|
bucket | string | name of your s3 bucket where attachments will be uploaded |
awsRegion | string | name of the aws region where s3 bucket is hosted |
awsKey | string | aws access key (recommended that it should be stored in environment variables) |
awsSecret | string | aws secret (recommended that it should be stored in environment variables) |
awsMediaConvertEndPoint | url string | aws media convert endpoint |
mediaConvertRole | string | name of aws media convert role |
cdnPrefix | url string | prefix in case your s3 bucket is behind a cdn |
Prop | Type | Description |
---|---|---|
mode | string | mode of render, should be either of "view", "edit" and "deleted" |
preventEditToView | boolean | flag, which is enables / disables the edit mode from going to view mode after submit |
clearOnSubmit | boolean | flag, which enables / disables clearing the editor after submit, in edit mode |
edited | boolean | flag, which shows / hides the 'Edited' decorator, in view mode |
showCancel | boolean | flag, which shows / hides the Cancel button on the editor, in edit mode |
showEdit | boolean | flag, which shows / hides the edit button, in view mode |
showDelete | boolean | flag, which shows / hides the delete button, in view mode |
showLikes | boolean | flag, which enables / disables the like button & functionality, in view mode |
showDisLikes | boolean | flag, which enables / disables the dislike button & functionality, in view mode |
showVotes | boolean | flag, which enables / disables the voting functionality, in view mode |
showShare | boolean | flag, which shows / hides the share button, in view mode |
iHaveLiked | boolean | flag, which sets / unsets whether the current user has liked, in view mode |
iHaveDisLiked | boolean | flag, which sets / unsets whether the current user has disliked, in view mode |
iHaveUpVoted | boolean | flag, which sets / unsets whether the current user has upvoted, in view mode |
iHaveDownVoted | boolean | flag, which sets / unsets whether the current user has downvoted, in view mode |
likes | number | number of likes, in view mode |
disLikes | number | number of dislikes, in view mode |
upVotes | number | number of upvotes, in view mode |
downVotes | number | number of downvotes, in view mode |
callbackInfo | json object | any json object can be provided, which is passed back by all callback functions |
replyTo | json object | any json object representing a comment to which the current comment is a reply, should follow the template {userName: "Sneha G", text: "Hey buddy!"} |
user | json object | any json object representing the current user, should follow the template {id: 2, name: "Hrushi M", picture: "picture_url", timestamp: "1660215594"} |
theme | theme object | superflows theme object |
Prop | Type | Description |
---|---|---|
onSubmit | callback | gets invoked after user submits, in edit mode |
onDelete | callback | gets invoked after user deletes, in view mode |
onLiked | callback | gets invoked after user likes, in view mode |
onLikeRemoved | callback | gets invoked after user removes like, in view mode |
onDisLiked | callback | gets invoked after user dislikes, in view mode |
onDisLikeRemoved | callback | gets invoked after user removes dislike, in view mode |
onReplied | callback | gets invoked after user clicks on reply, in view mode |
onShared | callback | gets invoked after user clicks on share, in view mode |
onUpVoted | callback | gets invoked after user upvotes, in view mode |
onUpVoteRemoved | callback | gets invoked after user removes upvote, in view mode |
onDownVoted | callback | gets invoked after user downvotes, in view mode |
onDownVoteRemoved | callback | gets invoked after user removes downvotes, in view mode |
onReplyTo | callback | gets invoked after user clicks on the source comment, in view mode |
onReplyToClosed | callback | gets invoked after user closes / removes the reply to section, in edit mode |
import React from 'react'
import { Col, Row, Container } from 'react-bootstrap';
import { CommentView } from 'react-commentview'
import Themes from 'react-ui-themes-superflows'
import 'bootstrap/dist/css/bootstrap.min.css';
const App = () => {
const theme = Themes.getTheme("Default");
return (
<Container className='mt-5'>
<Row className='justify-content-center'>
<Col sm={12} xs={12} md={6} xxl={6} >
<CommentView
mode="view"
showLikes={true}
showDisLikes={true}
iHaveLiked={true}
likes={5}
disLikes={10}
callbackInfo={{id: 22}}
preFill={{id: 10, text: 'Hello how are you doing? Hoping that things are going good at your end. Lets catchup soon, have something to discuss!'}}
user={{id: 2, name: "Hrushi M", picture: "https://image.shutterstock.com/mosaic_250/2780032/1714666150/stock-photo-head-shot-portrait-close-up-smiling-confident-businessman-wearing-glasses-looking-at-camera-1714666150.jpg", timestamp: "1660215594"}}
theme={theme}
onLiked={(result) => {console.log('liked result', result);}}
onLikeRemoved={(result) => {console.log('like removed result', result);}}
onDisLiked={(result) => {console.log('liked result', result);}}
onDisLikeRemoved={(result) => {console.log('dislike removed result', result);}}
onReplied={(result) => {console.log('reply result', result);}}
/>
</Col>
</Row>
</Container>
);
}
export default App
import React from 'react'
import { Col, Row, Container } from 'react-bootstrap';
import { CommentView } from 'react-commentview'
import Themes from 'react-ui-themes-superflows'
import 'bootstrap/dist/css/bootstrap.min.css';
const App = () => {
const theme = Themes.getTheme("Default");
return (
<Container className='mt-5'>
<Row className='justify-content-center'>
<Col sm={12} xs={12} md={6} xxl={6} >
<CommentView
mode="view"
showVotes={true}
iHaveUpVoted={true}
upVotes={25}
downVotes={10}
callbackInfo={{id: 22}}
preFill={{id: 10, text: 'Hello how are you doing? Hoping that things are going good at your end. Lets catchup soon, have something to discuss!'}}
user={{id: 2, name: "Hrushi M", picture: "https://image.shutterstock.com/mosaic_250/2780032/1714666150/stock-photo-head-shot-portrait-close-up-smiling-confident-businessman-wearing-glasses-looking-at-camera-1714666150.jpg", timestamp: "1660215594"}}
theme={theme}
onUpVoted={(result) => {console.log('upvoted result', result);}}
onUpVoteRemoved={(result) => {console.log('upvote removed result', result);}}
onDownVoted={(result) => {console.log('downvoted result', result);}}
onDownVoteRemoved={(result) => {console.log('downvote removed result', result);}}
onReplied={(result) => {console.log('reply result', result);}}
/>
</Col>
</Row>
</Container>
);
}
export default App
import React from 'react'
import { Col, Row, Container } from 'react-bootstrap';
import { CommentView } from 'react-commentview'
import Themes from 'react-ui-themes-superflows'
import 'bootstrap/dist/css/bootstrap.min.css';
const App = () => {
const theme = Themes.getTheme("Default");
return (
<Container className='mt-5'>
<Row className='justify-content-center'>
<Col sm={12} xs={12} md={6} xxl={6} >
<CommentView
bucket="your_bucket"
awsRegion="your_aws_region"
awsKey="your_aws_key"
awsSecret="your_aws_secret"
awsMediaConvertEndPoint="https://<endpoint_prefix>.mediaconvert.<region>.amazonaws.com"
mediaConvertRole="mediaconvert_role"
cdnPrefix="your_cdn_prefix"
mode="view"
showEdit={true}
showDelete={true}
showCancel={true}
showVotes={true}
iHaveUpVoted={true}
upVotes={25}
downVotes={10}
callbackInfo={{id: 22}}
preFill={{id: 10, text: 'Hello how are you doing? Hoping that things are going good at your end. Lets catchup soon, have something to discuss!'}}
user={{id: 2, name: "Hrushi M", picture: "https://image.shutterstock.com/mosaic_250/2780032/1714666150/stock-photo-head-shot-portrait-close-up-smiling-confident-businessman-wearing-glasses-looking-at-camera-1714666150.jpg", timestamp: "1660215594"}}
theme={theme}
onSubmit={(result) => {console.log('submit result', result);}}
onDelete={(result) => {console.log('delete result', result);}}
onReplied={(result) => {console.log('reply result', result);}}
onShared={(result) => {console.log('share result', result);}}
onUpVoted={(result) => {console.log('upvoted result', result);}}
onUpVoteRemoved={(result) => {console.log('upvote removed result', result);}}
onDownVoted={(result) => {console.log('downvoted result', result);}}
onDownVoteRemoved={(result) => {console.log('downvote removed result', result);}}
/>
</Col>
</Row>
</Container>
);
}
export default App
import React from 'react'
import { Col, Row, Container } from 'react-bootstrap';
import { CommentView } from 'react-commentview'
import Themes from 'react-ui-themes-superflows'
import 'bootstrap/dist/css/bootstrap.min.css';
const App = () => {
const theme = Themes.getTheme("Default");
return (
<Container className='mt-5'>
<Row className='justify-content-center'>
<Col sm={12} xs={12} md={6} xxl={6} >
<CommentView
bucket="your_bucket"
awsRegion="your_aws_region"
awsKey="your_aws_key"
awsSecret="your_aws_secret"
awsMediaConvertEndPoint="https://<endpoint_prefix>.mediaconvert.<region>.amazonaws.com"
mediaConvertRole="mediaconvert_role"
cdnPrefix="your_cdn_prefix"
mode="view"
showEdit={true}
showDelete={true}
showVotes={true}
iHaveUpVoted={true}
upVotes={25}
downVotes={10}
replyTo={{userName: "Sneha G", text: "Hey buddy!"}}
preFill={{id: 10, text: 'Hello how are you doing? Hoping that things are going good at your end. Lets catchup soon, have something to discuss!'}}
user={{id: 2, name: "Hrushi M", picture: "https://image.shutterstock.com/mosaic_250/2780032/1714666150/stock-photo-head-shot-portrait-close-up-smiling-confident-businessman-wearing-glasses-looking-at-camera-1714666150.jpg", timestamp: "1660215594"}}
theme={theme}
onSubmit={(result) => {console.log('submit result', result);}}
onDelete={(result) => {console.log('delete result', result);}}
onReplied={(result) => {console.log('reply result', result);}}
onShared={(result) => {console.log('share result', result);}}
onUpVoted={(result) => {console.log('upvoted result', result);}}
onUpVoteRemoved={(result) => {console.log('upvote removed result', result);}}
onDownVoted={(result) => {console.log('downvoted result', result);}}
onDownVoteRemoved={(result) => {console.log('downvote removed result', result);}}
onReplyTo={(result) => {console.log('reply to result', result);}}
/>
</Col>
</Row>
</Container>
);
}
export default App
import React from 'react'
import { Col, Row, Container } from 'react-bootstrap';
import { CommentView } from 'react-commentview'
import Themes from 'react-ui-themes-superflows'
import 'bootstrap/dist/css/bootstrap.min.css';
const App = () => {
const theme = Themes.getTheme("Default");
return (
<Container className='mt-5'>
<Row className='justify-content-center'>
<Col sm={12} xs={12} md={6} xxl={6} >
<CommentView
bucket="your_bucket"
awsRegion="your_aws_region"
awsKey="your_aws_key"
awsSecret="your_aws_secret"
awsMediaConvertEndPoint="https://<endpoint_prefix>.mediaconvert.<region>.amazonaws.com"
mediaConvertRole="mediaconvert_role"
cdnPrefix="your_cdn_prefix"
mode="edit"
showEdit={true}
showDelete={true}
showVotes={true}
iHaveUpVoted={true}
upVotes={25}
downVotes={10}
replyTo={{userName: "Sneha G", text: "Hey buddy!"}}
preFill={{id: 10, text: 'Hello how are you doing? Hoping that things are going good at your end. Lets catchup soon, have something to discuss!'}}
user={{id: 2, name: "Hrushi M", picture: "https://image.shutterstock.com/mosaic_250/2780032/1714666150/stock-photo-head-shot-portrait-close-up-smiling-confident-businessman-wearing-glasses-looking-at-camera-1714666150.jpg", timestamp: "1660215594"}}
theme={theme}
onSubmit={(result) => {console.log('submit result', result);}}
onDelete={(result) => {console.log('delete result', result);}}
onReplied={(result) => {console.log('reply result', result);}}
onShared={(result) => {console.log('share result', result);}}
onUpVoted={(result) => {console.log('upvoted result', result);}}
onUpVoteRemoved={(result) => {console.log('upvote removed result', result);}}
onDownVoted={(result) => {console.log('downvoted result', result);}}
onDownVoteRemoved={(result) => {console.log('downvote removed result', result);}}
onReplyTo={(result) => {console.log('reply to result', result);}}
/>
</Col>
</Row>
</Container>
);
}
export default App
Appearance customization can be done by modifying the theme object that is passed as a prop. Customizable properties of this component are listed below.
Before passing the theme object as prop to the component, you can change these colors as you wish so that component blends in perfectly in your user interface.
This example demonstrates how the theme object can be utilized to change the color scheme to night mode.
import React from 'react'
import { Col, Row, Container } from 'react-bootstrap';
import { CommentView } from 'react-commentview'
import Themes from 'react-ui-themes-superflows'
import 'bootstrap/dist/css/bootstrap.min.css';
const App = () => {
const theme = Themes.getTheme("Default");
theme.commentViewBorderColor = '#dddddd'
theme.commentViewBackgroundColor = '#000000'
theme.commentViewUserColor = '#ffffff'
theme.commentViewColor = '#dddddd'
theme.commentViewReplyToBackgroundColor = '#222222';
theme.commentViewReplyToTitleColor = '#cccccc';
theme.commentViewDecorationColor = '#ff0000';
theme.commentViewDecorationHighlightColor = '#00ff00';
theme.uploadToS3BackgroundColor = '#efefef'
return (
<Container className='mt-5'>
<Row className='justify-content-center'>
<Col sm={12} xs={12} md={6} xxl={6} >
<CommentView
bucket="your_bucket"
awsRegion="your_aws_region"
awsKey="your_aws_key"
awsSecret="your_aws_secret"
awsMediaConvertEndPoint="https://<endpoint_prefix>.mediaconvert.<region>.amazonaws.com"
mediaConvertRole="mediaconvert_role"
cdnPrefix="your_cdn_prefix"
mode="view"
showEdit={true}
showDelete={true}
showVotes={true}
iHaveUpVoted={true}
upVotes={25}
downVotes={10}
replyTo={{userName: "Sneha G", text: "Hey buddy!"}}
preFill={{id: 10, text: 'Hello how are you doing? Hoping that things are going good at your end. Lets catchup soon, have something to discuss!'}}
user={{id: 2, name: "Hrushi M", picture: "https://image.shutterstock.com/mosaic_250/2780032/1714666150/stock-photo-head-shot-portrait-close-up-smiling-confident-businessman-wearing-glasses-looking-at-camera-1714666150.jpg", timestamp: "1660215594"}}
theme={theme}
onSubmit={(result) => {console.log('submit result', result);}}
onDelete={(result) => {console.log('delete result', result);}}
onReplied={(result) => {console.log('reply result', result);}}
onShared={(result) => {console.log('share result', result);}}
onUpVoted={(result) => {console.log('upvoted result', result);}}
onUpVoteRemoved={(result) => {console.log('upvote removed result', result);}}
onDownVoted={(result) => {console.log('downvoted result', result);}}
onDownVoteRemoved={(result) => {console.log('downvote removed result', result);}}
onReplyTo={(result) => {console.log('reply to result', result);}}
/>
</Col>
</Row>
</Container>
);
}
export default App
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicListGet",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:List*",
"s3:Get*"
],
"Resource": [
"arn:aws:s3:::myuploads",
"arn:aws:s3:::myuploads/*"
]
}
]
}
[
{
"AllowedHeaders": [
"*"
],
"AllowedMethods": [
"PUT",
"POST",
"DELETE",
"GET"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": []
}
]
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:*",
"s3-object-lambda:*"
],
"Resource": "arn:aws:s3:::myuploads"
}
]
}
AWS mediaconvert is required for video processing. The clip selection happens at the client end, whereas the actual clipping is done by an AWS mediaconvert job. This requires a region specific endpoint and can be easily obtained from the aws cli (aws commandline).
aws mediaconvert describe-endpoints --region <region>
Remember that this region specific endpoint also has to be provided as a prop to the upload-to-s3 component. (Refer to the Usage Section)
Once you are through with installing the dependencies and the AWS configuration, using the component becomes fairly simple. Please refer to the Usage below.
PASS src/index.test.js (77.093s)
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
---|---|---|---|---|---|
All files | 78.27 | 66.91 | 76.67 | 78.32 | |
CommentView.js | 78.89 | 67.65 | 75.86 | 78.95 | ... 62,724,774,809 |
Constants.js | 100 | 100 | 100 | 100 | |
Util.js | 69.57 | 41.67 | 100 | 69.57 | ... 33,37,44,45,49 |
index.js | 0 | 0 | 0 | 0 | |
---------------- | ---------- | ---------- | ---------- | ---------- | ------------------- |
Test Suites: 1 passed, 1 total | |||||
Tests: 17 passed, 17 total | |||||
Snapshots: 0 total | |||||
Time: 78.601s | |||||
Ran all test suites. |
MIT © superflows-dev
FAQs
A reusable react component to show comments or discussions on a particular topic
The npm package react-commentview receives a total of 21 weekly downloads. As such, react-commentview popularity was classified as not popular.
We found that react-commentview demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security Fundamentals
The Socket Threat Research Team uncovers how threat actors weaponize shell techniques across npm, PyPI, and Go ecosystems to maintain persistence and exfiltrate data.
Security News
At VulnCon 2025, NIST scrapped its NVD consortium plans, admitted it can't keep up with CVEs, and outlined automation efforts amid a mounting backlog.
Product
We redesigned our GitHub PR comments to deliver clear, actionable security insights without adding noise to your workflow.