Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
nwjs-dialog
Advanced tools
File dialog and message box for NW.js.
npm install nwjs-dialog
Shows an open dialog.
dialog.showOpenDialog([win, ]options)
win
(optional)options
(optional)
title
/ nwdirectorydesc
string (optional) - Dialog title.defaultPath
/ nwworkingdir
string (optional) - Default pathopenDirectory
/ nwdirectory
boolean (optional) - Select directory, false
by defaultmultiple
boolean (optional) - Allow multiple files to be selected, false
by defaultaccept
string (optional) - Defines the file types should acceptreturnFormat
string (optional) - Return format, "string"
or "file"
, "string"
by defaultReturns Promise<string[] | File[]>
- Resolve with an array of files or file paths chosen by the user.
The win
argument allows the dialog to attach itself to a parent window, making it modal.
multiple
and accept
have no effect when openDirectory
(nwdirectory
) is true
.
title
(nwdirectorydesc
) valid only when openDirectory
(nwdirectory
) is true
.
const { showOpenDialog } = require("nwjs-dialog");
showOpenDialog().then(([filePath]) => {
console.log(filePath);
});
showOpenDialog({
title: "Dialog title",
defaultPath: process.cwd(),
openDirectory: false,
multiple: true,
accept: "audio/*,video/*,image/*,.txt",
returnFormat: "string",
}).then((filePaths) => {
console.log(filePaths);
});
Shows a save dialog.
dialog.showSaveDialog([win, ]options)
win
(optional)options
(optional)
defaultPath
/ nwworkingdir
string (optional) - Default pathfilename
/ nwsaveas
string (optional) - Default filename for savingaccept
string (optional) - Defines the file types should acceptreturnFormat
string (optional) - Return format, "string"
or "file"
, "string"
by defaultReturns Promise<string[] | File[]>
- Resolve with an array of files or file paths chosen by the user.
The win
argument allows the dialog to attach itself to a parent window, making it modal.
When filename
(nwsaveas
) is omitted, the filename defaults to empty.
const fs = require("fs");
const { showSaveDialog } = require("nwjs-dialog");
showSaveDialog().then(([filePath]) => {
fs.writeFileSync(filePath, "Hello");
});
showSaveDialog({
defaultPath: process.cwd(),
filename: "1.txt",
accept: "audio/*,video/*,image/*,.txt",
returnFormat: "string",
}).then(([filePath]) => {
fs.writeFileSync(filePath, "Hello");
});
Shows a message box.
The first call will create a MessageBox directory in the working directory to store temporary html files and icon files.
const { showMessageBox } = require("nwjs-dialog");
showMessageBox({ message: "Message" });
showMessageBox({ message: "Something is wrong", type: "error" });
dialog.showMessageBox([win, ]options)
win
(optional) - If title
option is omitted, it will be the win's title.options
message
string - Content of the message boxtype
string (optional) - Can be "none", "info", "error", "question", "warning" or "success"buttons
string[] (optional) - Array of texts for buttonstitle
string (optional) - Title of the message boxdetail
string (optional) - Extra information of the messagecheckboxLabel
string (optional) - If provided, the message box will include a checkbox with the given labelcheckboxChecked
boolean (optional) - Initial checked state of the checkbox. false
by defaulticon
string (optional) - Custom iconid
string (optional) - Message box window idplatform
string (optional) - Message box style. "default", "win32" or "darwin". Follow the os by default
customStyle
string (optional) - Custom style for message box elementsinputOptions
object (optional) - User input optionsonLoad
function (win) => void
(optional) - Called when the message box was loaded.onClose
function (returnValue, win) => Promise<boolean|void>
(optional) - Called before the message box closes, return false
will prevents the window close.onValidate
function (errors, win) => void
(optional) - Called after input option validate, contains all input options errors, if everything is correct, it will be an empty array.Returns Promise<MessageBoxReturnValue>
- Resolve with an object containing the following:
button
number - The index of the clicked button. -1
if close button clicked.checkboxChecked
boolean - The checked state of the checkbox if checkboxLabel
was set.inputData
object - Data of the inputOptions
radios
number - The index of the checked radio of the inputOptions.radios
checkboxes
boolean[] - The checked states of the inputOptions.checkboxes
inputs
string[] - The values of the inputOptions.inputs
const { showMessageBox } = require("nwjs-dialog");
showMessageBox({
message: "Message",
type: "info",
buttons: ["OK", "Cancel"],
title: "Title",
detail: "Detail",
checkboxLabel: "Checkbox",
checkboxChecked: true,
icon: "",
platform: "default",
customStyle: ".win32 .button:first-child { border-color: #0078d7; }",
}).then(({ button, checkboxChecked }) => {
console.log(button);
console.log(checkboxChecked);
});
Main elements's class names:
/* .header */
.header-icon {}
.title {}
/* .body */
.body-icon {}
.message {}
.detail {}
/* .input-options */
.checkbox-label {}
.checkbox-input {}
.radio-label {}
.radio-input {}
.input-label {}
.input-input {}
.description {}
/* .footer */
.button {}
/* platforms */
.win32 * {}
.darwin * {}
/* types */
.none {}
.info {}
.question {}
.warning {}
.error {}
.success {}
You can add simple input options in message box.
inputOptions
object (optional) - User input options
radios
object[] (optional)
label
string (optional) - Text for the item's label.value
boolean (optional) - Default value for the item.description
string (optional) - Description for the item.checkboxes
object[] (optional)
label
string (optional) - Text for the item's label.value
boolean (optional) - Default value for the item.description
string (optional) - Description for the item.required
boolean (optional) - Whether the checkbox must be checked.inputs
object[] (optional)
label
string (optional) - Text for the item's label.value
string (optional) - Default value for the item.description
string (optional) - Description for the item.placeholder
string (optional) - Placeholder for input.password
string (optional) - Set to password input.required
boolean (optional) - Whether the input is required.rule
RegExp | (value: string) => boolean
(optional) - Validation rule for the input. e.g. /^\d+$/
const { showMessageBox } = require("nwjs-dialog");
showMessageBox({
title: "Input Options",
inputOptions: {
radios: [
{ label: "Radio 1" },
{ label: "Radio 2", value: true, description: "Description" },
],
checkboxes: [
{ label: "Checkbox 1", description: "Description" },
{ label: "Checkbox 2", value: true },
],
inputs: [
{
label: "Input 1",
placeholder: "Placeholder",
description: "Description",
},
{
label: "Input 2",
value: "123456",
password: true,
description: "Password Input",
},
],
},
}).then(({ button, inputData }) => {
if (button === 0) {
const { radios, checkboxes, inputs } = inputData;
console.log({ radios, checkboxes, inputs });
}
});
inputOptions
validatorsconst { showMessageBox } = require("nwjs-dialog");
showMessageBox({
title: "Simple Inputs Validators",
inputOptions: {
checkboxes: [
{ label: "Checkbox", required: true, description: "Required" },
],
inputs: [
{ label: "Input 1", value: "", required: true, description: "Required" },
{
label: "Input 2",
value: "abc",
rule: /^[0-9]+$/,
description: "A RegExp rule. This input can only have numbers.",
},
{
label: "Input 2",
value: "Value",
rule: (value) => value === "ssnangua",
description: "A function rule. This input must be `ssnangua`.",
},
],
},
// Called after input option validate, contains all input options errors, if everything is correct, it will be an empty array.
onValidate(errors, win) {
win.window.document
.querySelector(".button:first-child")
.classList[errors.length > 0 ? "add" : "remove"]("disabled");
},
});
Here is a simple login window example:
const { showMessageBox } = require("nwjs-dialog");
const customStyle = `.message {
margin: 0 auto;
}
.button {
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 2px 8px;
}
.darwin .button {
padding: 4px 8px;
}
.button:first-child {
background: #409eff;
color: #fff;
}
.button:first-child:hover {
background: #66b1ff;
}
.button:last-child {
background: #fff;
border-color: #dcdfe6;
}
.button:last-child:hover {
background: #ecf5ff;
border-color: #c6e2ff;
color: #409eff;
}`;
showMessageBox({
id: "loginWin",
message: "Awesome Web App",
type: "none",
buttons: ["Login", "Cancel"],
title: "Login",
checkboxLabel: 'Agree to the <a href="#" target="_blank">User Agreement</a>.',
checkboxChecked: true,
icon: "./images/user.png",
customStyle,
inputOptions: {
inputs: [
{ label: "User", placeholder: "Nickname / Email" },
{ label: "Password", value: "", password: true },
],
checkboxes: [{ label: "Remenber me" }],
},
onClose({ button, checkboxChecked, inputData }, win) {
if (button === 0) {
const [user, password] = inputData.inputs;
if (!user || !password) {
win.window.alert("User and password cannot be empty.");
// You can modify the elements of message box, too.
// win.window.document.querySelector(".message").style.color = "red";
return false;
} else if (!checkboxChecked) {
win.window.alert("You need to agree to the User Agreement.");
return false;
} else {
// Can return a promise and you can send network requests to validate the data
return new Promise((resolve) => {
setTimeout(() => {
if (user !== "ssnangua") {
win.window.alert("Incorrect user or password.");
resolve(false);
} else {
resolve(true);
}
}, 1000);
});
}
}
},
}).then(({ button, inputData }) => {
if (button === 0) {
const [user, password] = inputData.inputs;
const [remenberMe] = inputData.checkboxes;
console.log(user, password, remenberMe);
}
});
NOTE
If the message box was opened through another window, the resolve handler will be lost when the window is closed.
So if you need to do some important processing on user input, you should open the message box in bg-script.
Or you can make the window uncloseable until the message box is closed:
let msgbox = true;
showMessageBox({
message: "A modal message box",
}).then(() => (msgbox = false));
const curWin = nw.Window.get();
curWin.on("close", () => {
if (!msgbox) curWin.close(true);
});
Or use with nwjs-window-manager
:
npm install nwjs-window-manager
const { wm } = require("nwjs-window-manager");
showMessageBox({
message: "A modal message box",
onLoad(win) {
wm(win, {
parent: nw.Window.get(),
modal: true,
});
},
});
nw.require(...)
instead of import ... from ...
to import path
and fs
.showOpenDialog
and showSaveDialog
add returnFormat
option.nwdirectorydesc
-> title
, nwworkingdir
-> defaultPath
, nwdirectory
-> openDirectory
, nwsaveas
-> filename
FAQs
File dialog and message box for NW.js.
The npm package nwjs-dialog receives a total of 1 weekly downloads. As such, nwjs-dialog popularity was classified as not popular.
We found that nwjs-dialog 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 News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.