
Research
/Security News
Critical Vulnerability in NestJS Devtools: Localhost RCE via Sandbox Escape
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
@contensis/html-canvas
Advanced tools
Convert HTML content to Contensis canvas
Install with your project's preferred package manager
npm install --save @contensis/html-canvas
yarn add --save @contensis/html-canvas
Convert a simple HTML snippet to Canvas JSON
import { parseHtml } from '@contensis/html-canvas';
const html = '<h1>test</h1>';
const canvas = await parseHtml(html);
// Output raw canvas to console
console.log(JSON.stringify(canvas, null, 2));
Create a HTML Parser, passing in configuration to allow the parser to prepare the canvas according to a specific field configuration in a content type.
Prepare a Delivery API client so the parser can find the field configuration and attempt to match external resources (such as images and links) to existing content in this Contensis project.
import { createHtmlParser } from '@contensis/html-canvas';
import { Client } from 'contensis-delivery-api';
const html = '<h1>test</h1>';
// Connect a Delivery API client
const client = Client.create({
clientDetails: { clientId: '', clientSecret: '' },
clientType: 'client_credentials',
projectId: '',
rootUrl: '',
versionStatus: 'latest'
});
// Create a HTML parser targeting the content type and field with the right Canvas configuration
const { parse } = await createHtmlParser({ client, contentTypeId: 'document', fieldId: 'canvas' });
// Use the parse function returned above to parse the HTML string and generate canvas JSON
const canvas = await parse(html);
A more complete example of converting existing entry data in a rich text field type to a canvas representation
import { createHtmlParser, Block } from '@contensis/html-canvas';
import { Client, ZenqlQuery } from 'contensis-delivery-api';
// Connect a Delivery API client
const client = Client.create({
clientDetails: { clientId: '', clientSecret: '' },
clientType: 'client_credentials',
projectId: '',
rootUrl: '',
versionStatus: 'latest'
});
// Create a HTML parser targeting the content type and field with the right Canvas configuration
const { parse } = await createHtmlParser({ client, contentTypeId: 'document', fieldId: 'canvas' });
// Get some entries containing richText field
const query = new ZenqlQuery(`sys.contentTypeId = document AND richText EXISTS`);
query.pageSize = 10;
const entries = await client.entries.search(query);
const canvasData: { [id: string]: Block[] } = {};
// Iterate through the page of search results
for (const entry of entries.items) {
if (entry.richText) {
// Parse the richText field content and convert to Canvas
const canvas = await parse(entry.richText);
// Keep a note of the updated entry data
canvasData[entry.sys.id] = canvas;
}
}
for (const [entryId, canvas] of Object.entries(canvasData)) {
// Log canvas data to console
console.log(`Entry: ${entryId}, Canvas: \n${JSON.stringify(canvas, null, 2)}`);
}
Further customisation is available by overriding specific parts of the parser and call the canvas parse
function directly
// Import the standalone `parse` method, and the `DataResolver` interface
import { DataResolver, createHtmlParser, parse } from '@contensis/html-canvas';
import { Client } from 'contensis-delivery-api';
const html = '<h1>test</h1>';
// Connect a Delivery API client
const client = Client.create({
clientDetails: { clientId: '', clientSecret: '' },
clientType: 'client_credentials',
projectId: '',
rootUrl: '',
versionStatus: 'latest'
});
// Create a HTML parser targeting the content type and field with the right Canvas configuration
// - returning the base elements to call the raw `parse` function
const { parserSettings, resolver, settings } = await createHtmlParser({ client, contentTypeId: 'document', fieldId: 'canvas' });
// Create a class implementing DataResolver, it needs to implement three methods for locating external resources
class CustomResolver implements DataResolver {
constructor(public client: Client) {
// Add what you need in the constructor here when an external reference is found
// and your `get...ByPath` method is called e.g. API client
}
async getAssetByPath(path: string) {
const asset = await resolver.getAssetByPath(path);
if (!asset) {
// implement custom logic for resolving / handling asset links
}
return asset;
}
async getEntryByPath(path: string) {
return resolver.getEntryByPath(path);
}
async getNodeByPath(path: string) {
const node = resolver.getNodeByPath(path);
if (!node) {
// implement custom logic for handling unresolved site view nodes
}
return node;
}
}
// Disallow element type heading (for example)
settings['type.heading'] = false;
// Instantiate our custom resolver so it is ready to use
const customResolver = new CustomResolver(client);
// Call the imported `parse` function providing all the required arguments
const canvas = await parse(html, settings, parserSettings, resolver);
You try this out with the HTML-to-canvas example project
Clone the @contenis/canvas repository and run npm install
, cd
into the packages/html-canvas
directory and run npm run build
then npm run test:mock
to run through the tests
npm test
will run the tests against a real API, for this you will need to create a .env
file in the package root with the following details in it:
rootUrl=""
projectId=""
clientId=""
sharedSecret=""
You will need to first ensure the .env
file mentioned above is in place and all the existing tests are passing with npm test
When the new test(s) are added and passing:
npm run test:record
*(you can limit this to run specific tests with describe.only(...
in mocha)
npm run test:mock
so we can see all tests working with the new mock data.FAQs
Convert HTML to Contensis Canvas
We found that @contensis/html-canvas demonstrated a healthy version release cadence and project activity because the last version was released less than 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.
Research
/Security News
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
Product
Customize license detection with Socket’s new license overlays: gain control, reduce noise, and handle edge cases with precision.
Product
Socket now supports Rust and Cargo, offering package search for all users and experimental SBOM generation for enterprise projects.