Security News
The Push to Ban Ransom Payments Is Gaining Momentum
Ransomware costs victims an estimated $30 billion per year and has gotten so out of control that global support for banning payments is gaining momentum.
backblaze-b2
Advanced tools
Changelog
v1.4.0 (June 3, 2019) - The Application Key / Streams release
Features
applicationKeyId
parameter for proper use of application keys. (#67 - thanks @phil-r)Readme
A customizable B2 client for Node.js:
axios
and axiosOverride
config arguments) and at the global level (see axios
config argument at instantiation) so you can use any axios feature.retries
argument at instantiation.This library uses promises, so all actions on a B2
instance return a promise in the following pattern:
b2.instanceFunction(arg1, arg2).then(
successFn(response) { ... },
errorFn(err) { ... }
);
const B2 = require('backblaze-b2');
const b2 = new B2({
applicationKeyId: 'applicationKeyId', // or accountId: 'accountId'
applicationKey: 'applicationKey' // or masterApplicationKey
});
async function GetBucket() {
try {
await b2.authorize(); // must authorize first
let response = await b2.getBucket({ bucketName: 'my-bucket' });
console.log(response.data);
} catch (err) {
console.log('Error getting bucket:', err);
}
}
Each request returns an object with:
status
- int, html error StatusstatusText
headers
config
request
data
- actual returned data from backblaze, https://www.backblaze.com/b2/docs/calling.htmlEach action (see reference below) takes arguments and constructs an axios request. You can add additional axios options at the request level using:
axios
argument (object): each property in this object is added to the axios request object only if it does not conflict with an existing property.axiosOverride
argument (object): each property in this object is added to the axios request object by overriding conflicting properties, if any. Don't use this unless you know what you're doing!axios
and axiosOverride
work by recursively merging properties, so if you pass axios: { headers: { 'your-custom-header': 'header-value' } }
, the entire headers object will not be overridden - each header property (your-custom-header
) will be compared.const B2 = require('backblaze-b2');
// All functions on the b2 instance return the response from the B2 API in the success callback
// i.e. b2.foo(...).then((b2JsonResponse) => {})
// create B2 object instance
const b2 = new B2({
applicationKeyId: 'applicationKeyId', // or accountId: 'accountId'
applicationKey: 'applicationKey', // or masterApplicationKey
// optional:
axios: {
// overrides the axios instance default config, see https://github.com/axios/axios
},
retry: {
retries: 3 // this is the default
// for additional options, see https://github.com/softonic/axios-retry
}
});
// common arguments - you can use these in any of the functions below
const common_args = {
// axios request level config, see https://github.com/axios/axios#request-config
axios: {
timeout: 30000 // (example)
},
axiosOverride: {
/* Don't use me unless you know what you're doing! */
}
}
// authorize with provided credentials
b2.authorize({
// ...common arguments (optional)
}); // returns promise
// create bucket
b2.createBucket({
bucketName: 'bucketName',
bucketType: 'bucketType' // one of `allPublic`, `allPrivate`
// ...common arguments (optional)
}); // returns promise
// delete bucket
b2.deleteBucket({
bucketId: 'bucketId'
// ...common arguments (optional)
}); // returns promise
// list buckets
b2.listBuckets({
// ...common arguments (optional)
}); // returns promise
// get the bucket
b2.getBucket({
bucketName: 'bucketName',
bucketId: 'bucketId' // optional
// ...common arguments (optional)
}); // returns promise
// update bucket
b2.updateBucket({
bucketId: 'bucketId',
bucketType: 'bucketType'
// ...common arguments (optional)
}); // returns promise
// get upload url
b2.getUploadUrl({
bucketId: 'bucketId'
// ...common arguments (optional)
}); // returns promise
// upload file
b2.uploadFile({
uploadUrl: 'uploadUrl',
uploadAuthToken: 'uploadAuthToken',
fileName: 'fileName',
contentLength: 0, // optional data length, will default to data.byteLength or data.length if not provided
mime: '', // optional mime type, will default to 'b2/x-auto' if not provided
data: 'data', // this is expecting a Buffer, not an encoded string
hash: 'sha1-hash', // optional data hash, will use sha1(data) if not provided
info: {
// optional info headers, prepended with X-Bz-Info- when sent, throws error if more than 10 keys set
// valid characters should be a-z, A-Z and '-', all other characters will cause an error to be thrown
key1: 'value'
key2: 'value'
},
onUploadProgress: (event) => {} || null // progress monitoring
// ...common arguments (optional)
}); // returns promise
// list file names
b2.listFileNames({
bucketId: 'bucketId',
startFileName: 'startFileName',
maxFileCount: 100,
delimiter: '',
prefix: ''
// ...common arguments (optional)
}); // returns promise
// list file versions
b2.listFileVersions({
bucketId: 'bucketId',
startFileName: 'startFileName',
maxFileCount: 100
// ...common arguments (optional)
}); // returns promise
// hide file
b2.hideFile({
bucketId: 'bucketId',
fileName: 'fileName'
// ...common arguments (optional)
}); // returns promise
// get file info
b2.getFileInfo({
fileId: 'fileId'
// ...common arguments (optional)
}); // returns promise
// get download authorization
b2.getDownloadAuthorization({
bucketId: 'bucketId',
fileNamePrefix: 'fileNamePrefix',
validDurationInSeconds: 'validDurationInSeconds', // a number from 0 to 604800
b2ContentDisposition: 'b2ContentDisposition'
// ...common arguments (optional)
}); // returns promise
// download file by name
b2.downloadFileByName({
bucketName: 'bucketName',
fileName: 'fileName',
responseType: 'arraybuffer', // options are as in axios: 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
onDownloadProgress: (event) => {} || null // progress monitoring
// ...common arguments (optional)
}); // returns promise
// download file by fileId
b2.downloadFileById({
fileId: 'fileId',
responseType: 'arraybuffer', // options are as in axios: 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
onDownloadProgress: (event) => {} || null // progress monitoring
// ...common arguments (optional)
}); // returns promise
// delete file version
b2.deleteFileVersion({
fileId: 'fileId',
fileName: 'fileName'
// ...common arguments (optional)
}); // returns promise
// start large file
b2.startLargeFile({
bucketId: 'bucketId',
fileName: 'fileName'
// ...common arguments (optional)
}); // returns promise
// get upload part url
b2.getUploadPartUrl({
fileId: 'fileId'
// ...common arguments (optional)
}); // returns promise
// get upload part
b2.uploadPart({
partNumber: 'partNumber', // A number from 1 to 10000
uploadUrl: 'uploadUrl',
uploadAuthToken: 'uploadAuthToken', // comes from getUploadPartUrl();
data: Buffer // this is expecting a Buffer not an encoded string,
hash: 'sha1-hash', // optional data hash, will use sha1(data) if not provided
onUploadProgress: (event) => {} || null // progress monitoring
// ...common arguments (optional)
}); // returns promise
// finish large file
b2.finishLargeFile({
fileId: 'fileId',
partSha1Array: [partSha1Array] // array of sha1 for each part
// ...common arguments (optional)
}); // returns promise
// cancel large file
b2.cancelLargeFile({
fileId: 'fileId'
// ...common arguments (optional)
}); // returns promise
To upload large files, you should split the file into parts (between 5MB and 5GB) and upload each part seperately.
First, you initiate the large file upload to get the fileId:
let response = await b2.startLargeFile({ bucketId, fileName });
let fileId = response.data.fileId;
Then for each part you request an uploadUrl
, and use the response to upload the part:
let response = await b2.getUploadPartUrl({ fileId });
let uploadURL = response.data.uploadUrl;
let authToken = response.data.authorizationToken;
response = await b2.uploadPart({
partNumber: parNum,
uploadUrl: uploadURL,
uploadAuthToken: authToken,
data: buf
});
// status checks etc.
Then finish the uploadUrl:
let response = await b2.finishLargeFile({
fileId,
partSha1Array: parts.map(buf => sha1(buf))
})
See the CHANGELOG for a history of updates.
For this update, we've switched the back end HTTP request library from request
to axios
as it has better Promise and progress support built in. However, there are a couple changes that will break your code and ruin your day. Here are the changes:
res
), this data now resides in res.data
.then()
. Because we are no longer using the same promise library, this functionality has been removed. However, progress reporting is still available by passing a callback function into the b2.method()
that you're calling. See the documentation below for details.b2.downloadFileById()
accepted a fileId
parameter as a String or Number. As of 1.0.0, the first parameter is now expected to be a plain Object of arguments.Contributions, suggestions, and questions are welcome. Please review the contributing guidelines for details.
FAQs
Node.js Library for the Backblaze B2 Storage Service
We found that backblaze-b2 demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 5 open source maintainers 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
Ransomware costs victims an estimated $30 billion per year and has gotten so out of control that global support for banning payments is gaining momentum.
Application Security
New SEC disclosure rules aim to enforce timely cyber incident reporting, but fear of job loss and inadequate resources lead to significant underreporting.
Security News
The Python Software Foundation has secured a 5-year sponsorship from Fastly that supports PSF's activities and events, most notably the security and reliability of the Python Package Index (PyPI).