
Security News
Scaling Socket from Zero to 10,000+ Organizations
Socket CEO Feross Aboukhadijeh shares lessons from scaling a developer security startup to 10,000+ organizations in this founder interview.
@nearform/commentami-backend-hapi-plugin
Advanced tools
@nearform/commentami-backend-hapi-plugin is a plugin to add the commentami REST API and (if specified) Websockets to a Hapi (17+) server. It relies on the @nearform/commentami-backend-core module.
To install via npm:
npm install @nearform/commentami-backend-hapi-plugin
@nearform/commentami-backend-hapi-plugin has some options you can specifiy to customize it
options.pg [optional]It should contain an object with the postgres connection parameters.
options.pg = {
host: '127.0.0.1',
port: 9876
}
Any parameter in this object will override whatever comes from @nearform/commentami-backend-core config.pg.
options.routes [optional]Through the routes option you can configure @nearform/commentami-backend-hapi-plugin to have it's routes protected behind an authentication strategy and add the cors handling by Hapi:
options.routes = {
cors: true,
auth: 'myauth'
}
If you want @nearform/commentami-backend-hapi-plugin to populate the author field when adding a comment, you can provide the following function:
options.routes = {
auth: 'myauth',
getUserFromRequest: async (request, payload) => {
// ...
return user
}
}
The getUserFromRequest function will need to return a promise that will yield either null or an object with the property username (ie : { username: 'test', ... }). We will store that username value as the author identifier. Beware that author will be stored as a string.
options.hooks [optional]It should contain the hooks to decorate a single comment, a list of comments or the involved users when fetched from the database.
An example could be adding users data to each comment based on its author or populating the users data when loading all the users involved in a discusssion.
options.hooks = {
fetchedComment: async (comment) => {
// ... fetch user data
return augmentedComment
},
fetchedComments: async (comments) => {
// ... fetch users data
return augmentedComments
},
involvedUsers: [async] users => {
// add your data to the involved users ...
return users
}
}
Note: A user will be always represented as an object { username: '...' }.
options.multines [optional]By default the server will start with only the http endpoints available. If you also want to interact through websocket you should provide a multines option.
The option should be an object with the following format
multines: {
type: 'redis', // only "redis" or "mongo"
// specific configurations for redis/mongo
host: '127.0.0.1',
port: 6379
}
Note: if you pass options.multines = {} the websockets will be active but the pub/sub system will work only for the single server and not between multiple servers.
options.nes [optional]If you want to customize the nes plugin you can pass its options through options.nes.
An example of what you may want to do is settig up nes to use an authentication strategy that you have already added to you server
nes: {
auth: {
type: 'token',
route: 'myauth'
}
}
options.resolvers.resolveUrl [optional]The commentami library requires the url of a resource to build the deeplink. A resultUrl(comment) should be provided if you want to use the deep link functionality.
options.resolvers = {
resolveUrl: async (comment) => {
// resource = comment.resource
// ... resolve the page that contains the specific resource
return baseUrl
}
}
Under the hood @nearform/commentami-backend-hapi-plugin add a commentsService object to both server and request.
If you need to be notified when a comment is added, deleted or updated you can use this object to add your listeners.
server.commentsService.on('add', (comment) => { /*...*/ })
server.commentsService.on('update', (comment) => { /*...*/ })
server.commentsService.on('delete', (comment) => { /*...*/ })
An example on how to install the plugin with all the options and events listeners:
const main = async function() {
const server = require('hapi').Server({ host: 'localhost', port: 80 })
const options = {
hooks: {
fetchedComment: async comment => {
// ...
return augmentedComment
},
fetchedComments: async comments => {
//...
return augmentedComments
},
involvedUsers: async users => {
// add your data to the involved users ...
return users
}
},
pg: {
host: '127.0.0.1',
port: 5432
},
multines: {
type: 'redis',
host: '127.0.0.1',
port: 6379
},
nes: {
auth: {
type: 'token',
route: 'myauth'
}
},
routes: {
auth: 'myauth',
getUserFromRequest: async (request, payload) => {
// ...
return user
}
},
resolvers: {
resolveUrl: async (comment) => {
// ...
return baseUrl
}
}
}
await server.register([
{
plugin: require('@nearform/commentami-backend-hapi-plugin', options)
}
])
server.commentsService.on('add', comment => {
/* send sms */
})
server.commentsService.on('add', comment => {
/* send email */
})
server.commentsService.on('delete', comment => {
/* store deleted comments somewhere else */
})
server.commentsService.on('update', comment => {
/* log the updated comment somewhere */
})
await server.start()
logMessage(`Server running at: ${server.info.uri}`)
}
main().catch(console.error)
The plugin mounts the following endpoints
GET /comments-references/{resource*}This endpoint will return the list of references linked to a resource.
GET /comments-references/some-resource
{
resource: `some-resource`,
references: [ 'ref1', 'ref2', ... ]
}
GET /comments?resource={resource}[&reference={reference}][&limit={limit}][&offset={offset}]This endpoint will return a paginated list of comments relative to a resource (this parameter is required) and a reference (when specified)
GET /comments?resource=some-resource
{
comments: [ ... ],
total: 10,
limit: 100
offset: 0
}
The list is paginated based on limit (default 100) and offset (default 0) parameters.
GET /comments{id}This endpoint will return a single comment
GET /comments/1234
{
id: 1234,
resource: 'some-resource',
reference: 'some-reference',
content: 'some content',
author: { username: 'author' },
mentions: []
createdAt: 2018-05-31T08:01:25.296Z
}
The list is paginated based on limit (default 100) and offset (default 0) parameters.
POST /commentsThis endpoint will create a new comment.
The body of the request is as follow and all parameters but author are required
POST /comments
{
resource: 'some-resource',
reference: 'some-reference',
content: 'some content',
author: { username: 'author' }
}
PUT /comments/{id}This endpoint will update the content of a comment
POST /comments/{id}
{
content: 'some new content'
}
DELETE /comments/{id}This endpoint will delete a comment
POST /comments/{id}
If you enabled multines on the server (see options) you will be able to use a nes client to communicate with it through websocket.
A nes client will map all the server HTTP API enpoints
client = new Nes.Client('ws://<my-server>')
await client.connect()
const response = await client.request(`/comments-references/${this.resource}`) // list comments
// or
const response = await client.request({ // create a new comment
method: 'POST',
path: `/comments`,
payload: {
resource: 'URL',
reference: 'UUID',
content: 'MESSAGE'
}
})
When a comment is added/updated/deleted, clients subscribed to receive updates on its resource and optionally reference will be notified.
client = new Nes.Client('ws://127.0.0.1:8281')
await client.connect()
await client.subscribe(`/resources/some-resource`, (event) => {
// do something
})
await client.subscribe(`/resources-reference/some-reference/some-resource`, (event) => {
// do something
})
The event object will have the following format
{
comment: {
id: 1234,
resource: 'URL',
reference: 'UUID',
content: 'MESSAGE',
author: { username: 'AUTHOR' },
createdAt: 2018-05-31T08:01:25.296Z,
mentions: []
},
action: 'add'
}
The action property can have one of the following values: add, delete or update.
If a user is involved in the discussion (posted a comment on the same resource/reference) it will be notified of new comments posted on the same resource/reference. If a user is mentioned (@<username>) in a comment content, it will be notified.
If the plugin has been configured with the resolveUrl function, the notification objects will also have a url paramenter with the deep link to the comment.
client = new Nes.Client('ws://127.0.0.1:8281')
await client.connect()
await client.subscribe(`/users/some-username`, (event) => {
// do something
})
The event object will have the following format
{
comment: {
id: 1234,
resource: 'RESOURCE-ID',
reference: 'UUID',
content: 'MESSAGE',
author: { username: 'AUTHOR' },
createdAt: 2018-05-31T08:01:25.296Z,
mentions: []
},
action: 'mention',
url: 'http://someurl.com/the-path-to-the-resource?resource=RESOURCE-ID&reference=UUID&comment=1234'
}
The action property can have one of the following values: mention, involve.
You will need a postgres server up and running.
To create the db needed for the tests you can use the following command
npm run pg:test:init
and the run
npm test
To run a single test you can use the following command
npx lab <test/to/run.js> // (ie: npx lab test/index.test.js)
Copyright nearForm Ltd 2018. Licensed under Apache 2.0 license.
FAQs
Commentami
We found that @nearform/commentami-backend-hapi-plugin demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 37 open source maintainers 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 News
Socket CEO Feross Aboukhadijeh shares lessons from scaling a developer security startup to 10,000+ organizations in this founder interview.

Research
Socket Threat Research maps a rare inside look at OtterCookie’s npm-Vercel-GitHub chain, adding 197 malicious packages and evidence of North Korean operators.

Research
Socket researchers identified a malicious Chrome extension that manipulates Raydium swaps to inject an undisclosed SOL transfer, quietly routing fees to an attacker wallet.