
Security News
/Research
Popular node-ipc npm Package Infected with Credential Stealer
Socket detected malicious node-ipc versions with obfuscated stealer/backdoor behavior in a developing npm supply chain attack.
@appgeist/storage
Advanced tools
An opinionated Express-based storage server featuring assets uploading and on-demand image-resizing, like a self-hosted Cloudinary

An opinionated Express-based storage server featuring assets uploading and on-demand image-resizing. Like a self-hosted Cloudinary.
Uses ImageMagick, multer and UUID.
Requires ImageMagick with WebP support. Most linux distributions provide it by default and brew install imagemagick is everything you need to run to install it on macOS.
Because:
jpg, png or gif;Simple, with default options:
const storage = require("@appgeist/storage");
storage().listen(3000, err => {
if (err) throw err;
// eslint-disable-next-line no-console
console.log("Storage server running...");
});
As Express middleware, with custom config options:
const express = require("express");
const storage = require("@appgeist/storage");
const app = express();
app.use(
"/assets",
storage({
storageDir: "./files",
tmpDir: "./temp-uploads",
maxUploadSize: 1024 * 1024 * 50, // 50 megabytes
pictureQuality: 90,
maxPicturePixels: 3840 * 2160 // 4K
})
);
app.listen(3000, err => {
if (err) throw err;
// eslint-disable-next-line no-console
console.log("Server running...");
});
See @appgeist/example-storage-simple and @appgeist/example-storage-with-auth for more.
Have a look at index.js to see the default config options; JSDoc comments are provided for IDE support.
Files can be uploaded by POSTing to the mountpoint or a subfolder (i.e. POST /assets or POST /assets/a/subfolder/to/store/the/uploaded/files) with the following body payload:
{
file: fileData;
}
...where file represents the file multipart/form-data (provided, for instance by an <input type="file" /> tag, see multer docs for more info).
Instead of simply uploading a file, the server can be instructed to dowload it from an accesible remote location by POSTing a URL instead of file data:
{
url: "http://example.com/catz.jpg";
}
The uploaded file will end up in ${storageDir}/assets or a subfolder, such as ${storageDir}/assets/a/subfolder/to/store/the/uploaded/files.
A UUID/v4-based name will be generated for the uploaded file.
If the uploaded file is an image (jpg/webp/png/gif), it will be converted to webp using ImageMagick library and resized to maxPicturePixels, otherwise it will simply be stored in the original format.
Examples:
catz.jpg to /assets will generate a file like /assets/9752d427-e6e2-4868-8abf-720db82421c2.webp;doc.pdf to /assets/docs will generate a file like /assets/docs/9752d427-e6e2-4868-8abf-720db82421c2.pdf;When succesfully uploading catz.jpg to /assets/pics/animals, the server will respond with the following JSON:
{
"path": "/pics/animals",
"uuid": "9752d427-e6e2-4868-8abf-720db82421c2",
"isPicture": true,
"originalName": "catz.jpg",
"aspectRatio": 1.77778
}
...where:
true (and false for non-picture uploads);identify utility; this property is only present for picture file uploads).Stored picture files can be served in multiple formats, resized/centered/cropped to a specified size.
Assuming a 9752d427-e6e2-4868-8abf-720db82421c2 uuid was issued by a previous picture upload, new files will be generated and served to GET requests like so:
/9752d427-e6e2-4868-8abf-720db82421c2.webp
will serve the original picture;/9752d427-e6e2-4868-8abf-720db82421c2-w800-h600.webp
will serve the picture resized/centered/cropped to a width of 800px and a height of 600px;/9752d427-e6e2-4868-8abf-720db82421c2-w50-h50-lq.webp
will serve a low-quality picture resized/centered/cropped to 50x50 pixels (useful for LQIPs).Cropping and resizing only work for pictures. Other types of assets will only be served in the original format.
Files generated for different sizes and formats are never deleted. This can quickly eat up your server space. Make sure to implement your own mechanism to delete old/unnecessary files!!!
The ISC License.
FAQs
An opinionated Express-based storage server featuring assets uploading and on-demand image-resizing, like a self-hosted Cloudinary
The npm package @appgeist/storage receives a total of 2 weekly downloads. As such, @appgeist/storage popularity was classified as not popular.
We found that @appgeist/storage 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
Socket detected malicious node-ipc versions with obfuscated stealer/backdoor behavior in a developing npm supply chain attack.

Security News
TeamPCP and BreachForums are promoting a Shai-Hulud supply chain attack contest with a $1,000 prize for the biggest package compromise.

Security News
Packagist urges PHP projects to update Composer after a GitHub token format change exposed some GitHub Actions tokens in CI logs.