npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

joi-html-input

v2.0.1

Published

Joi validations for inputs that accept html

Downloads

1,681

Readme

joi-html-input

A Joi extension for sanitizing and validating html inputs.

Installation

Installation using yarn:

$ yarn add joi-html-input

Installation using npm:

$ npm install joi-html-input

Sanitization

To remove unwanted tags from the user input you can use .allowedTags() to pass the input through sanitize-html. By default this will strip things like <script> and <iframe> tags but leave in most other common tags.

const htmlInput = require('joi-html-input')
const Joi = require('joi').extend(htmlInput)

const htmlString = '<div>Test<script>alert(\'test\');</script></div>'
const joiSchema = Joi.htmlInput().allowedTags()
const results = joiSchema.validate(htmlString)

console.log(results)

/* Expected output:
{ value: '<div>Test</div>' }
*/

If you want more control over what html tags and attributes are allowed you can pass an options object to .allowedTags() which will be passed directly to sanitize-html so see thier documentation for details but here is an example.

const htmlInput = require('joi-html-input')
const Joi = require('joi').extend(htmlInput)

const sanitizeConfig = {
  'allowedTags': [
    'h1',
    'span'
  ],
  'allowedAttributes': {
    'span': [
      'style'
    ]
  }
}

const htmlString = '<h1><span class="align-left" style="color:red;">Test Link</span></h1>'

const joiSchema = Joi.htmlInput().allowedTags(sanitizeConfig)
const results = joiSchema.validate(htmlString)

console.log(results)

/* Expected output:
{ value: '<h1><span style="color:red">Test Link</span></h1>' }
*/

Additional Methods

.htmlInput() extends the builtin Joi.string() method so you can use any of the built in string methods including .length() .min() and .max() and they will work the same as you would expect when using Joi.string() these could be useful if you want to validate the maximum length of a string so that you don't exceed a character limit in your database however you may run into problems if you are using a WYSIWYG editor like TinyMCE or CKEditor and want to set a character limit but you don't want the generated html for bulletpoints, links or styling to count towards that character limit.

To help you validate your HTML strings based on the actual length they will be when displayed in the browser .htmlInput() provides several methods. These menthods will also account for html entities such as &nbsp; so that they only count as single character.

The tag stripping for these methods is provided by sanitize-html and the decoding of HTML entities is provided by html-entities.

.displayLength(limit, [encoding])

Validates the length of a string ignoring HTML tags and converting HTML entities to characters. The return value remains unchanged.

const htmlInput = require('joi-html-input')
const Joi = require('joi').extend(htmlInput)

const htmlString = '<div><h1 class="align-center">Test&nbsp;Heading</h1></div>'
const joiSchema = Joi.htmlInput().displayLength(12)
const results = joiSchema.validate(htmlString)

console.log(results)

/* Expected output:
{ value: '<div><h1 class="align-center">Test&nbsp;Heading</h1></div>' }
*/

.displayMin(limit, [encoding])

Validates the minimum number of characters in a string ignoring HTML tags and converting HTML entities to characters. The return value remains unchanged.

const htmlInput = require('joi-html-input')
const Joi = require('joi').extend(htmlInput)

const htmlString = '<div><h1 class="align-center">Test&nbsp;Heading</h1></div>'
const joiSchema = Joi.htmlInput().displayMin(12)
const results = joiSchema.validate(htmlString)

console.log(results)

/* Expected output:
{ value: '<div><h1 class="align-center">Test&nbsp;Heading</h1></div>' }
*/

.displayMax(limit, [encoding])

Validates the maximum number of characters in a string ignoring HTML tags and converting HTML entities to characters. The return value remains unchanged.

const htmlInput = require('joi-html-input')
const Joi = require('joi').extend(htmlInput)

const htmlString = '<div><h1 class="align-center">Test&nbsp;Heading</h1></div>'
const joiSchema = Joi.htmlInput().displayMax(12)
const results = joiSchema.validate(htmlString)

console.log(results)

/* Expected output:
{ value: '<div><h1 class="align-center">Test&nbsp;Heading</h1></div>' }
*/

Additional Examples

Here are some more examples that you might find useful. If you have any suggestions for additional examples please submit them via a pull request on github.

Character Encoding

Just like the builtin Joi.string().length() the .displayLength() .displayMin() and .displayMax() also have support for an optional encoding parameter, here is an example.

const htmlInput = require('joi-html-input')
const Joi = require('joi').extend(htmlInput)

const htmlString = '<div><span class="small-text">Copywrite \u00A9</span></div>'

// With out utf8 character encoding the length of this string will be 16
const joiSchema1 = Joi.htmlInput().displayLength(12)
const results1 = joiSchema1.validate(htmlString)

// So this will produce an error
console.log(results1)

/* Expected output:
{
  value: '<div><span class="small-text">Copywrite ©</span></div>',
  error: [Error [ValidationError]: "value" length must be 12 characters long] {
    _original: '<div><span class="small-text">Copywrite ©</span></div>',
    details: [ [Object] ]
  }
}
*/

// With utf8 character encoding the length of this string will be 12
// Note: \u00A9 = 2 characters
const joiSchema2 = Joi.htmlInput().displayLength(12, 'utf8')
const results2 = joiSchema2.validate(htmlString)

// So this will validate
console.log(results2)

/* Expected output:
{ value: '<div><span class="small-text">Copywrite ©</span></div>' }
*/

Sanitization And Validation Together

All the additonal methods provided by .htmlInput() can be chained with other methods including those provided by Joi. Here is an example of multiple methods being used together.

const sanitizeConfig = {
  'allowedTags': [
    'h1'
  ],
  'allowedAttributes': {
    'h1': [
      'id'
    ]
  }
}

const htmlString = '<h1 id="headline">Test Heading<script>alert(\'Test\')</script></h1>'
const joiSchema = Joi.htmlInput().allowedTags(sanitizeConfig).displayLength(12).max(50)
const results = joiSchema.validate(htmlString)

console.log(results)

/* Expected output:
{ value: '<h1 id="headline">Test Heading</h1>' }
*/

Compatibility

Updated and tested for use with Joi 17.6.0 and node 16.14.0

Disclaimer

This package is not an official part of Joi nor is it produced by any member of the Joi team. It is not security tested, if you want to use this package in your project please read the full license first (link below) and review the code for yourself before using.

License

BSD-3-Clause