Dive into secure and efficient coding practices with our curated list of the top 10 examples showcasing 'sodium-native' in functional components in JavaScript. Our advanced machine learning engine meticulously scans each line of code, cross-referencing millions of open source libraries to ensure your implementation is not just functional, but also robust and secure. Elevate your React applications to new heights by mastering the art of handling side effects, API calls, and asynchronous operations with confidence and precision.
// do not use destructuring or it will deopt
const split = cookie.split(';')
const cyphertextB64 = split[0]
const nonceB64 = split[1]
if (split.length <= 1) {
// the cookie is malformed
request.session = new Session({})
next()
return
}
const cipher = Buffer.from(cyphertextB64, 'base64')
const nonce = Buffer.from(nonceB64, 'base64')
if (cipher.length < sodium.crypto_secretbox_MACBYTES) {
// not long enough
request.session = new Session({})
next()
return
}
const msg = Buffer.allocUnsafe(cipher.length - sodium.crypto_secretbox_MACBYTES)
if (!sodium.crypto_secretbox_open_easy(msg, cipher, nonce, key)) {
// unable to decrypt
request.session = new Session({})
next()
return
}
request.session = new Session(JSON.parse(msg))
next()
async init (size) {
await super.init(size)
// Create sodium buffer
this._alignSize = Math.ceil(size / 8) * 8
this._b = sodium.sodium_malloc(this._alignSize)
// lock it
sodium.sodium_mprotect_noaccess(this._b)
// Destructor: Clear buffer memory
this.$pushDestructor(() => {
// normally sodium free would clear the buffer...
// but since we're waiting for js gc, let's clear it now
sodium.sodium_mprotect_readwrite(this._b)
this._b.fill(0)
sodium.sodium_mprotect_noaccess(this._b)
this._b = null
})
}
async init (size) {
await super.init(size)
this._alignSize = Math.ceil(size / 8) * 8
this._b = sodium.sodium_malloc(this._alignSize)
sodium.sodium_mprotect_noaccess(this._b)
this.$pushDestructor(() => {
// normally sodium free would clear the buffer...
// but since we're waiting for js gc, let's clear it now
sodium.sodium_mprotect_readwrite(this._b)
this._b.fill(0)
sodium.sodium_mprotect_noaccess(this._b)
this._b = null
})
}
async init (size) {
await super.init(size)
this._alignSize = Math.ceil(size / 8) * 8
this._b = sodium.sodium_malloc(this._alignSize)
sodium.sodium_mprotect_noaccess(this._b)
this.$pushDestructor(() => {
// normally sodium free would clear the buffer...
// but since we're waiting for js gc, let's clear it now
sodium.sodium_mprotect_readwrite(this._b)
this._b.fill(0)
sodium.sodium_mprotect_noaccess(this._b)
this._b = null
})
}
async init (size) {
await super.init(size)
// Create sodium buffer
this._alignSize = Math.ceil(size / 8) * 8
this._b = sodium.sodium_malloc(this._alignSize)
// lock it
sodium.sodium_mprotect_noaccess(this._b)
// Destructor: Clear buffer memory
this.$pushDestructor(() => {
// normally sodium free would clear the buffer...
// but since we're waiting for js gc, let's clear it now
sodium.sodium_mprotect_readwrite(this._b)
this._b.fill(0)
sodium.sodium_mprotect_noaccess(this._b)
this._b = null
})
}
export function vaultToHexString(organizationVaultSecret: string, vault: Vault): string {
const vaultString = JSON.stringify(vault);
const plaintextBuffer = Buffer.from(vaultString);
// The nonce/salt will be prepended to the ciphertext:
const dataBuffer = Buffer.alloc(
sodium.crypto_secretbox_NONCEBYTES + sodium.crypto_secretbox_MACBYTES + vaultString.length,
);
// A new nonce/salt is used every time the vault is updated:
const nonceBuffer = dataBuffer.slice(0, sodium.crypto_secretbox_NONCEBYTES);
sodium.randombytes_buf(nonceBuffer);
const keyBuffer = toKeyBuffer(organizationVaultSecret);
const cipherBuffer = dataBuffer.slice(sodium.crypto_secretbox_NONCEBYTES);
sodium.crypto_secretbox_easy(cipherBuffer, plaintextBuffer, nonceBuffer, keyBuffer);
return dataBuffer.toString("hex");
}
salt,
sodium.crypto_pwhash_OPSLIMIT_MODERATE,
sodium.crypto_pwhash_MEMLIMIT_MODERATE,
sodium.crypto_pwhash_ALG_DEFAULT)
}
if (options.key) {
key = options.key
if (typeof key === 'string') {
key = Buffer.from(key, 'base64')
} else if (!(key instanceof Buffer)) {
return next(new Error('key must be a string or a Buffer'))
}
if (key.length < sodium.crypto_secretbox_KEYBYTES) {
return next(new Error(`key must be at least ${sodium.crypto_secretbox_KEYBYTES} bytes`))
}
}
if (!key) {
return next(new Error('key or secret must specified'))
}
const cookieName = options.cookieName || 'session'
const cookieOptions = options.cookieOptions || options.cookie || {}
// just to add something to the shape
// TODO verify if it helps the perf
fastify.decorateRequest('session', null)
fastify
.register(require('fastify-cookie'))
Buffer.from(options.secret),
salt,
sodium.crypto_pwhash_OPSLIMIT_MODERATE,
sodium.crypto_pwhash_MEMLIMIT_MODERATE,
sodium.crypto_pwhash_ALG_DEFAULT)
}
if (options.key) {
key = options.key
if (typeof key === 'string') {
key = Buffer.from(key, 'base64')
} else if (!(key instanceof Buffer)) {
return next(new Error('key must be a string or a Buffer'))
}
if (key.length < sodium.crypto_secretbox_KEYBYTES) {
return next(new Error(`key must be at least ${sodium.crypto_secretbox_KEYBYTES} bytes`))
}
}
if (!key) {
return next(new Error('key or secret must specified'))
}
const cookieName = options.cookieName || 'session'
const cookieOptions = options.cookieOptions || options.cookie || {}
// just to add something to the shape
// TODO verify if it helps the perf
fastify.decorateRequest('session', null)
fastify
export function vaultFromHexString(organizationVaultSecret: string, dataHexString: string): Vault {
// The nonce/salt is prepended to the actual ciphertext:
const dataBuffer = Buffer.from(dataHexString, "hex");
const nonceBuffer = dataBuffer.slice(0, sodium.crypto_secretbox_NONCEBYTES);
const cipherBuffer = dataBuffer.slice(sodium.crypto_secretbox_NONCEBYTES);
const keyBuffer = toKeyBuffer(organizationVaultSecret);
const plaintextBuffer = Buffer.alloc(cipherBuffer.length - sodium.crypto_secretbox_MACBYTES);
if (!sodium.crypto_secretbox_open_easy(plaintextBuffer, cipherBuffer, nonceBuffer, keyBuffer)) {
throw Error("Vault decryption failed!");
}
const vaultString = plaintextBuffer.toString();
const vault: Vault = JSON.parse(vaultString);
return vault;
}
export function encrypt(organizationSecret: string, plaintext: string): string {
const plaintextBuffer = Buffer.from(plaintext);
// The nonce/salt will be prepended to the ciphertext:
const dataBuffer = Buffer.alloc(
sodium.crypto_secretbox_NONCEBYTES + sodium.crypto_secretbox_MACBYTES + plaintextBuffer.length,
);
// A new nonce/salt is used every time the vault is updated:
const nonceBuffer = dataBuffer.slice(0, sodium.crypto_secretbox_NONCEBYTES);
sodium.randombytes_buf(nonceBuffer);
const keyBuffer = toKeyBuffer(organizationSecret);
const cipherBuffer = dataBuffer.slice(sodium.crypto_secretbox_NONCEBYTES);
sodium.crypto_secretbox_easy(cipherBuffer, plaintextBuffer, nonceBuffer, keyBuffer);
return dataBuffer.toString("hex");
}