New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

hapi-darwin

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

hapi-darwin - npm Package Compare versions

Comparing version 1.0.1 to 1.0.2

205

index.js

@@ -1,19 +0,13 @@

/*
* @tavousi / created as plugin for hapijs
* Hapi-darwin@v1.0.1 simple image storage
* focused on upload single image with imagemagick*
* ~fetures : just look apis ;)
* ~Problems :
* if set name in options for multiple mode you get bad results*
* if your file is duplicate, the darwin cant rename it*
* if you want to upload single file i suggest darwin***
* ~You need more ?
* write yourself !
/* Hapi-darwin 1.0.2 */
/* Multiple mode have lots of problems */
/*
darwin dont need eventEmitter because we using async...await
additional darwin handling errors with try...catch
*/
'use strict';
import os from 'os';
import * as fs from 'fs';
import async from 'async';
import mkdirp from 'mkdirp';
import { extname, join } from 'path';
import { promisify } from 'util';
import { basename, extname, join } from 'path';
import fileType from 'file-type';

@@ -25,23 +19,37 @@ import readChunk from 'read-chunk';

const sizeOf = promisify(require('image-size'));
internals.uploader = (file, options = {}) => {
if (!file) throw new Error('No file(s) recived !');
if (!file) throw new Error('No file(s) recived');
internals.options = Object.assign({
tmp: os.tmpdir(),
name: undefined,
filter: /\.(jpg|jpeg|png|gif)$/,
multiple: false,
// safeName: false, Soon
safeName: true,
delOrginal: false, // when using `imageVersions`
maxFiles: 1,
minFileSize: 0.001 * 1024 * 1024, // 10 KB
maxFileSize: 1 * 1024 * 1024, // 1 MB
maxFileSize: 1 * 1024 * 1024, // 1 MB
minHeight: 10, // in pixels
maxHeight: 10000, // in pixels
minWidth: 10, // in pixels
maxWidth: 10000, // in pixels
destination: './public/storage/null',
urlDestination: 'https://hapi-darwin/public/storage/null',
imageVersions: {
['thumbnail-80']: {
width: 80,
height: 80,
imageArgs: ['-auto-orient']
}
}
// imageVersions: {
// ['thumbnail-720']: {
// width: 2 * 720,
// height: 720,
// imageArgs: ['-auto-orient']
// },
// ['thumbnail-360']: {
// width: 2 * 360,
// height: 360,
// imageArgs: ['-auto-orient']
// }
// },
imageVersions: undefined
}, internals.options, options);

@@ -51,3 +59,3 @@

if (file.length > internals.options.maxFiles) throw new Error('Maximum files recived !');
if (file.length > internals.options.maxFiles) throw new Error('Maximum files recived');

@@ -59,3 +67,3 @@ const promises = file.map(each => internals._fileHandler(each));

} else {
if (file.length > 1) throw new Error('Maximum files recived !');
if (file.length > 1) throw new Error('Maximum files recived');

@@ -75,3 +83,4 @@ return internals._fileHandler(file);

internals.validateAfterRecived = (fileDetails) => {
internals.validateAfterRecived = async (fileDetails) => {
const dimensions = await sizeOf(fileDetails.path);
const buffer = readChunk.sync(fileDetails.path, 0, 4100);

@@ -88,19 +97,51 @@ const file = fileType(buffer);

} else if (!internals.options.filter.test(`x.${file.ext}`)) {
error = 'Filetype (chunk) not allowed';
error = 'Filetype not allowed';
} else if (internals.options.minHeight && internals.options.minHeight > dimensions.height) {
error = `Minimum height should be ${internals.options.minHeight}px`;
} else if (internals.options.maxHeight && internals.options.maxHeight < dimensions.height) {
error = `Maximum height should be ${internals.options.maxHeight}px`;
} else if (internals.options.minWidth && internals.options.minWidth > dimensions.width) {
error = `Minimum width should be ${internals.options.minWidth}px`;
} else if (internals.options.maxWidth && internals.options.maxWidth < dimensions.width) {
error = `Maximum width should be ${internals.options.maxWidth}px`;
}
return !error;
return error;
};
internals._fileHandler = (file) => {
internals.safeNameFs = async (filename) => {
// Prevent directory traversal and creating hidden system files:
let name = basename(filename.toString()).replace(/^\.+/, '');
// Prevent overwriting existing files:
while (fs.existsSync(join(internals.options.destination, name))) {
name = name.replace(/(?:(?:_\(([\d]+)\))?(\.[^.]+))?$/, (s, index, ext) => `_(${(parseInt(index, 10) || 0) + 1})${ext || ''}`);
}
return name;
};
internals._fileHandler = async (file) => {
const orignalname = file.hapi.filename;
const filename = internals.options.name ? `${internals.options.name}${extname(orignalname)}` : orignalname;
let filename = internals.options.name ? `${internals.options.name}${extname(orignalname)}` : orignalname;
if (internals.options.safeName) {
filename = await internals.safeNameFs(filename);
}
const path = join(internals.options.destination, filename);
const fileStream = fs.createWriteStream(path);
const imageVersions = Object.keys(internals.options.imageVersions);
const tmpName = `_darwin_${Date.now()}_${filename}`;
const tmpPath = join(internals.options.tmp, tmpName);
const fileStream = fs.createWriteStream(tmpPath);
const imageVersions = internals.options.imageVersions ? Object.keys(internals.options.imageVersions) : [];
if (!internals.validateBeforReciving(orignalname)) {
throw new Error('type not allowed');
throw new Error('Filetype not allowed');
}

@@ -127,3 +168,4 @@

url: join(internals.options.urlDestination, filename),
size: fs.statSync(path).size,
size: fs.statSync(tmpPath).size,
delOrginal: internals.options.delOrginal ? true : false,
versions: imageVersions.length > 0 ? {} : undefined

@@ -134,37 +176,63 @@ }

const validate = await internals.validateAfterRecived(fileDetails);
const validate = await internals.validateAfterRecived({
path: tmpPath,
size: fileDetails.size
});
if (!validate) {
fs.unlinkSync(fileDetails.path);
return reject(validate);
if (validate) {
await internals.deleteFileFs(tmpPath);
return reject(new Error(validate));
}
if (imageVersions.length === 0) finish();
mkdirp(internals.options.destination, (err, made) => {
fs.rename(tmpPath, path, err => {
if (!err) {
generateVersions();
} else {
const is = fs.createReadStream(tmpPath);
const os = fs.createWriteStream(path);
is.on('end', async err => {
if (!err) {
await internals.deleteFileFs(path);
generateVersions();
}
});
is.pipe(os);
}
});
});
let counter = 0;
imageVersions.forEach(version => {
mkdirp(join(internals.options.destination, version), (err, made) => {
const opts = internals.options.imageVersions[version];
imageMagick.resize({
width: opts.width,
height: opts.height,
srcPath: join(internals.options.destination, filename),
dstPath: join(internals.options.destination, version, filename),
customArgs: opts.imageArgs || ['-auto-orient']
}, (err, stdout, stderr) => {
const generateVersions = () => {
if (internals.options.imageVersions === undefined) finish();
else {
let counter = 0;
imageVersions.forEach(version => {
mkdirp(join(internals.options.destination, version), (err, made) => {
const opts = internals.options.imageVersions[version];
imageMagick.resize({
width: opts.width,
height: opts.height,
srcPath: join(internals.options.destination, filename),
dstPath: join(internals.options.destination, version, filename),
customArgs: opts.imageArgs || ['-auto-orient']
}, async (err, stdout, stderr) => {
if (err) throw err;
counter++;
if (err) throw err;
counter++;
fileDetails.versions[version] = {
destination: join(internals.options.destination, version),
urlDestination: join(internals.options.urlDestination, version),
path: join(internals.options.destination, version, filename),
url: join(internals.options.urlDestination, version, filename)
}
fileDetails.versions[version] = {
destination: join(internals.options.destination, version),
urlDestination: join(internals.options.urlDestination, version),
path: join(internals.options.destination, version, filename),
url: join(internals.options.urlDestination, version, filename)
}
if (imageVersions.length === counter) finish();
if (imageVersions.length === counter) {
if (internals.options.delOrginal) await internals.deleteFileFs(path);
finish();
}
});
});
});
});
});
}
}
})

@@ -174,2 +242,6 @@ })

internals.deleteFileFs = async (filePath) => {
fs.unlinkSync(filePath);
};
export function register(server, options, next) {

@@ -179,3 +251,4 @@

server.expose('uploader', internals.uploader);
server.expose('uploader', internals.uploader);
server.expose('deleteFileFs', internals.deleteFileFs);

@@ -186,3 +259,3 @@ next();

exports.register.attributes = {
pkg: require('./package.json')
};
name: 'hapi-darwin'
};
{
"name": "hapi-darwin",
"version": "1.0.1",
"description": "image storage",
"version": "1.0.2",
"description": "simple image storage",
"main": "index.js",

@@ -27,3 +27,10 @@ "scripts": {

"lab": "11.x.x"
},
"dependencies": {
"file-type": "^7.4.0",
"image-size": "^0.6.1",
"imagemagick": "^0.1.3",
"mkdirp": "^0.5.1",
"read-chunk": "^2.1.0"
}
}

@@ -64,4 +64,40 @@ # hapi-darwin

## Config
```js
internals.options = Object.assign({
tmp: os.tmpdir(),
name: undefined,
filter: /\.(jpg|jpeg|png|gif)$/,
multiple: false,
safeName: true,
delOrginal: false, // when using `imageVersions`
maxFiles: 1,
minFileSize: 0.001 * 1024 * 1024, // 10 KB
maxFileSize: 1 * 1024 * 1024, // 1 MB
minHeight: 10, // in pixels
maxHeight: 10000, // in pixels
minWidth: 10, // in pixels
maxWidth: 10000, // in pixels
destination: './public/storage/null',
urlDestination: 'https://hapi-darwin/public/storage/null',
imageVersions: {
['thumbnail-720']: {
width: 2 * 720,
height: 720,
imageArgs: ['-auto-orient']
},
['thumbnail-360']: {
width: 2 * 360,
height: 360,
imageArgs: ['-auto-orient']
}
},
// imageVersions: undefined
}, internals.options, options);
```
## License
MIT
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc