Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
electron-secure-pos-printer
Advanced tools
A secure POS (point of sale) printer for Electron. By default, supports 58mm printers, however, it is very configurable, and is designed such that it can even be used without Electron (provided you supply the correct shims).
Note: The API for this module is inspired by electron-pos-printer, however it is NOT the same, so please pay close attention below if you are transitioning over from electron-pos-printer
.
NPM:
$ npm install electron-secure-pos-printer
Yarn:
$ yarn add electron-secure-pos-printer
The module requires only that you configure it in the main Electron process. No script imports or configuration are needed for the renderer HTML.
Step 1: Configure the IPC hooks for the main process
main.js
const Path = require('path');
const Electron = require('electron');
const { setupSecurePOSPrinter } = require('electron-secure-pos-printer');
var mainWindow;
function createWindow() {
mainWindow = new Electron.BrowserWindow({
width: 800,
height: 600,
show: true,
webPreferences: {
preload: Path.join(__dirname, 'preload.js')
},
});
// Load your app/site into the main window
mainWindow.loadFile(Path.join(__dirname, 'main.html'));
mainWindow.on('closed', function () {
mainWindow = null;
});
}
const app = Electron.app;
app.on('ready', () => {
// Setup secure bridge with renderer
setupSecurePOSPrinter(Electron);
createWindow();
});
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', function () {
if (mainWindow === null) {
createWindow();
}
});
Step 2: Preload for renderer process
preload.js
const { contextBridge, ipcRenderer } = require('electron');
const { setupSecureBridge } = require('electron-secure-pos-printer');
// Setup secure bridge with main process
setupSecureBridge(contextBridge, ipcRenderer);
Step 3: Inside your HTML
<!DOCTYPE html>
<html>
<head>
<title>Secure POS Printer Test</title>
<script>
// This global is exposed by Electron
/* global securePOSPrinter */
async function test() {
// Get a list of attached printers
var printers = await securePOSPrinter.getPrinters();
// Print some data
var data = [
{
type: 'text',
value: 'Testing 123',
},
{
type: 'qrCode',
value: 'https://www.saltlakefilmsociety.org/',
options: {
scale: 4,
},
},
{
type: 'barCode',
value: 123456789999,
},
{
// Path to image on file system
// mimeType is required when loading images from the file system
type: 'image',
path: './assets/printer-image.png',
mimeType: 'image/png',
}
{
// You can also specify a "src" attribute directly
type: 'image',
src: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAIAAABLbSncAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5gIREQQbbUH0CgAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAMUlEQVQI13WOQQ4AIAzCWv//53kwmjiFYyGAAFBVbKmAjR7Ply6NK6Ufo7elqjye7k6T7hILeH2VsAAAAABJRU5ErkJggg==',
sectionStyle: {
alignItems: 'center',
justifyContent: 'center',
},
attributes: {
width: '100px',
height: '100px',
},
},
{
type: 'table',
header: [ 'Item', 'Price' ],
rows: [
[ 'Popcorn', '$5.00' ],
[ 'Soda', '$3.00' ],
[ 'Candy', '$2.00' ],
],
footer: [ 'Total', '$10.00' ],
},
];
var options = {
printerName: 'SomePrinterName',
// You can specify your own global stylesheet if you want
styleSheet: "body,#container { width: '110mm'}",
preview: true,
};
// Note: This promise will not resolve until
// 1) The preview window is shown, or
// 2) The document has been sent to the printer, or
// 3) An error occurred
await securePOSPrinter.print(data, options);
}
test();
</script>
</head>
<body>
</body>
</html>
Option | Description | Default Value |
---|---|---|
addFinalMargin | (boolean) If true , then add a little extra margin at the bottom of the print content | true |
bodyAttributes | (object) Attributes to assign directly to the body tag in the document | null |
containerAttributes | (object) Attributes to assign directly to the <div id="container"> element in the document. Inside this container is where all the data content is rendered | null |
copies | (number) number of copies to print | 1 |
developmentMode | (boolean) If true , then launch the dev-tools for the preview window (only works if preview is true ) | false |
htmlAttributes | (object) Attributes to assign directly to the html tag in the document | { lang: "en" } |
margin | (string) margin of a page, css values can be used | 0 |
pageSize | (string) Specify the page medium for the printer | 'A4' |
preview | (boolean) preview in a window | false |
previewWindowHeight | (number) height of the preview window (in pixels) | 720 |
previewWindowWidth | (number) width of the preview window (in pixels) | 360 |
printerName | (string) the printer's name | null |
printOptions | (object) Options to pass directly to Electron.WebContents.print | null |
silent | (boolean) To print silently without printer selection pop-up | true |
styleSheet | (string/object) A style sheet (not a file name) to apply globally to the document. This gets inserted in the head of the document. If this is an object, then the keys are selectors, and the values are StyleType | null |
Option | Description | Default |
---|---|---|
sectionStyle | (StyleType) style to apply to this section (the container of this content) | null |
style | (StyleType) style to apply to this type | null |
type | (string) One of 'text' , 'qrCode' , 'barCode' , 'image' , 'table' | 'text' |
Option | Description | Default |
---|---|---|
raw | (boolean) If true , then the value provided will not be wrapped in a <span> element | false |
value | (string) REQUIRED Content to put into this section | null |
Note: By using raw: true
to can specify any HTML code you want as the value
Example:
var data = [
{
type: 'text',
value: 'Some content!',
// if `true`, then don't wrap content in a <span>
raw: false,
// Style applied to the <span> element,
// ignored if "raw = true"
style: { fontWeight: 'bold' },
sectionStyle: {
alignItems: 'center',
justifyContent: 'center',
},
}
];
Option | Description | Default |
---|---|---|
attributes | (object) Attributes to assign to the <img> tag | null |
height | (number) Height in pixels for the generated QR code image | null |
options | (object) Options object to pass directly to qrcode.options | null |
value | (string) REQUIRED Content to encode into the QR code | null |
width | (number) Width in pixels for the generated QR code image | null |
Note: The QR code is generated with qrcode
as a PNG image encoded in a data:
URI.
Example:
var data = [
{
type: 'qrCode',
value: 'Some content!',
// Style applied to the <img> element
style: { width: '40mm', height: '40mm' },
sectionStyle: {
alignItems: 'center',
justifyContent: 'center',
},
options: {
scale: 10,
}
}
];
Option | Description | Default |
---|---|---|
attributes | (object) Attributes to assign to the <img> tag | null |
height | (number) Height in pixels for the generated bar code image | null |
options | (object) Options object to pass directly to jsbarcode.options | null |
value | (number) REQUIRED ID to encode into the bar code | null |
width | (number) Width in pixels for the generated bar code image | null |
Note: The barcode is generated with jsbarcode
as an SVG image encoded in a data:
URI.
Example:
var data = [
{
type: 'barCode',
value: 123456789999,
// Style applied to the <img> element
style: { width: '40mm' },
sectionStyle: {
alignItems: 'center',
justifyContent: 'center',
},
options: {
format: 'CODE128',
}
}
];
Option | Description | Default |
---|---|---|
attributes | (object) Attributes to assign to the <img> tag | null |
height | (number) Height in pixels for the image | null |
path | (string) Path on file system to image. If you specify this option then you must also specify a mimeType for the image | null |
mimeType | (string) This is required if you specify a path | null |
src | (string) Specify the src attribute of the image directly. If path is specified, that will take precedence over this option | null |
width | (number) Width in pixels for the image | null |
Note 1: One of path
+ mimeType
, or src
are required
Note 2: If path
is specified, the image will be loaded from disk, and encoded as a data:
URI, using the mimeType
you specified
Example:
var data = [
{
type: 'image',
path: './assets/some-image.png',
mimeType: 'image/png',
// Style applied to the <img> element
style: { width: '40mm', height: '40mm' },
sectionStyle: {
alignItems: 'center',
justifyContent: 'center',
},
},
{
type: 'image',
src: 'https://image-cdn.com/some-image.png',
// Style applied to the <img> element
style: { width: '40mm', height: '40mm' },
sectionStyle: {
alignItems: 'center',
justifyContent: 'center',
},
}
];
Option | Description | Default |
---|---|---|
bodyAttributes | (object) Attributes to assign to the <tbody> tag | null |
bodyStyle | (StyleType) Style to apply to the <tbody> tag | null |
columnAttributes | (object) Attributes to assign to all <td> tags | null |
columnStyle | (StyleType) Style to apply to all <td> tags | null |
footer | (array[string]) Columns for the footer. If not specified, then there will be no table footer | null |
footerAttributes | (object) Attributes to assign to the <tfoot> tag | null |
footerStyle | (StyleType) Style to apply to the <tfoot> tag | null |
header | (array[string]) Columns for the header. If not specified, then there will be no table header | null |
headerAttributes | (object) Attributes to assign to the <thead> tag | null |
headerStyle | (StyleType) Style to apply to the <thead> tag | null |
rowAttributes | (object) Attributes to assign to all <tr> or <th> tags | null |
rows | (array[array[string]]) REQUIRED An array (rows) of arrays (columns) for the table | null |
rowStyle | (StyleType) Style to apply to all <tr> or <th> tags | null |
tableAttributes | (object) Attributes to assign to the <table> tag | null |
tableStyle | (StyleType) Style to apply to the <table> tag | null |
Note: The number of columns must be the same for every row or an exception will be thrown
Example:
var data = [
{
type: 'table',
header: [ 'Item', 'Price' ],
rows: [
[ 'Popcorn', '$5.00' ],
[ 'Soda', '$3.00' ],
[ 'Candy', '$2.00' ],
],
footer: [ 'Total', '$10.00' ],
},
];
Styles can be applied to elements in a number of different ways. All of the following style definitions can validly be given to any style option:
'border-width: 0.5mm; color: red;'
{ borderWidth: '0.5mm', color: 'red' }
[ 'border-width: 0.5mm; color: red;', { borderWidth: '0.5mm', color: 'red' }, rootStyleObject ]
. If using an array of styles, then all styles will be parsed and merged into a single style sheet.Note: When using object notation for styles, if you use a number
for any value, then by default it will be converted into a mm
unit. For example, { width: 10 }
would be converted into 'width: 10mm'
automatically. If a certain style actually needs a raw number, then specify your style as a string instead.
The content that gets renderered for the printer has roughly the following structure:
<html>
<head>
<!-- Default and custom style sheets get injected here -->
</head>
<!-- The "preview" class is applied to the body if in preview mode -->
<body class="preview">
<div id="container">
<div class="section">
<!-- content from "data" goes here -->
</div>
<div class="section">
<!-- content from "data" goes here -->
</div>
...
</div>
</body>
</html>
Refer to ./src/main-style-sheet.css
for the default styles applied to the print document.
If you request preview: true
in the options, then extra scripts and content will be injected into the preview document to enable the "Cancel" and "Print" buttons at the top of the preview to function properly.
Many thanks to all our sponors!
This work was sponsored by MAST @ Salt Lake Film Society
FAQs
A secure POS (point of sale) printer for Electron
The npm package electron-secure-pos-printer receives a total of 10 weekly downloads. As such, electron-secure-pos-printer popularity was classified as not popular.
We found that electron-secure-pos-printer 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.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.