Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@phc/format

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@phc/format - npm Package Compare versions

Comparing version 0.3.5 to 0.4.0

90

index.js

@@ -10,2 +10,4 @@ /* eslint-disable max-params,capitalized-comments,complexity */

const b64Regex = /^([a-zA-Z0-9/+.-]+|)$/;
const degimalRegex = /(?<=\s|^)[-+]?\d+(?=\s|$)/;
const versionRegex = /^v=(\d+)$/;

@@ -38,5 +40,2 @@ function objToKeyVal(obj) {

}
function isNumeric(n) {
return !isNaN(parseFloat(n)) && isFinite(n);
}

@@ -48,4 +47,3 @@ /**

* @param {string} opts.id Symbolic name for the function.
* @param {string} [opts.raw] Additional raw data added after the identifier.
* It's here to support argon2 v parameter and to generate MCF formatted strings.
* @param {Number} [opts.version] The version of the function.
* @param {Object} [opts.params] Parameters of the function.

@@ -72,9 +70,15 @@ * @param {Buffer} [opts.salt] The salt as a binary buffer.

// This is to make argon2 format compatible
if (typeof opts.raw === 'string') {
fields.push(opts.raw);
if (typeof opts.version !== 'undefined') {
if (
typeof opts.version !== 'number' ||
opts.version < 0 ||
!Number.isInteger(opts.version)
) {
throw new TypeError('version must be a positive integer number');
}
fields.push(`v=${opts.version}`);
}
// Parameters Validation
if (typeof opts.params !== 'undefined') {
if (typeof opts.params !== 'undefined' && typeof opts.raw === 'undefined') {
if (typeof opts.params !== 'object' || opts.params === null) {

@@ -130,12 +134,5 @@ throw new TypeError('params must be an object');

* @param {string} phcstr A PHC string to parse.
* @param {boolean} [strict=true] If false does not throw an error if there is
* one filed not unrecognized. The content of the unrecognized filed will be
* stored in the raw property of the output object. This is useful to parse
* out of specs parameters like the 'v' present in the argon2 hash format or
* to parse MCF formatted strings.
* @return {Object} The object containing the data parsed from the PHC string.
*/
function deserialize(phcstr, strict) {
strict = strict !== false;
function deserialize(phcstr) {
if (typeof phcstr !== 'string' || phcstr === '') {

@@ -153,3 +150,3 @@ throw new TypeError('pchstr must be a non-empty string');

let maxf = 5;
if (strict) maxf--;
if (!versionRegex.test(fields[1])) maxf--;
if (fields.length > maxf) {

@@ -167,2 +164,8 @@ throw new TypeError(

let version;
// Parse Version
if (versionRegex.test(fields[0])) {
version = parseInt(fields.shift().match(versionRegex)[1], 10);
}
let hash;

@@ -186,42 +189,21 @@ let salt;

const parstr = fields.pop();
let isKeyVal = false;
try {
params = keyValtoObj(parstr);
isKeyVal = true;
} catch (err) {
if (strict) {
throw err;
}
fields.push(parstr);
params = keyValtoObj(parstr);
if (!objectKeys(params).every(p => nameRegex.test(p))) {
throw new TypeError(`params names must satisfy ${nameRegex}`);
}
if (isKeyVal) {
if (!objectKeys(params).every(p => nameRegex.test(p))) {
throw new TypeError(`params names must satisfy ${nameRegex}`);
}
const pv = objectValues(params);
if (!pv.every(v => valueRegex.test(v))) {
throw new TypeError(`params values must satisfy ${valueRegex}`);
}
const pk = objectKeys(params);
// Convert Numeric Strings into Numbers
pk.forEach(k => {
params[k] = isNumeric(params[k]) ? parseFloat(params[k]) : params[k];
});
const pv = objectValues(params);
if (!pv.every(v => valueRegex.test(v))) {
throw new TypeError(`params values must satisfy ${valueRegex}`);
}
const pk = objectKeys(params);
// Convert Decimal Strings into Numbers
pk.forEach(k => {
params[k] = degimalRegex.test(params[k])
? parseInt(params[k], 10)
: params[k];
});
}
// Parse Raw Data if not in strict mode
let raw;
if (fields.length > 0) {
if (strict) {
throw new TypeError(
`pchstr contains unrecognized fileds: ${fields.length}/0`
);
}
if (fields.length !== 1) {
throw new TypeError(
`pchstr contains too many unrecognized fileds: ${fields.length}/1`
);
}
raw = fields.pop();
throw new TypeError(`pchstr contains unrecognized fileds: ${fields}`);
}

@@ -231,6 +213,6 @@

const phcobj = {id};
if (version) phcobj.version = version;
if (params) phcobj.params = params;
if (salt) phcobj.salt = salt;
if (hash) phcobj.hash = hash;
if (raw) phcobj.raw = raw;

@@ -237,0 +219,0 @@ return phcobj;

2

package.json
{
"name": "@phc/format",
"version": "0.3.5",
"version": "0.4.0",
"description": "PHC string format serializer/deserializer",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -105,7 +105,4 @@ <h1 align="center">

You can also pass an optional version parameter.
Using the `raw` and `strict` parameters you can even serialize/deserialize
PHC strings that does not strictly adhere to the 'standard', like the one
used by [argon2](https://github.com/P-H-C/phc-winner-argon2/issues/157)
```js

@@ -116,3 +113,3 @@ const phc = require('@phc/format');

id: 'argon2i',
raw: 'v=19', ← Note the v parameter
version: 19,
params: {

@@ -126,3 +123,3 @@ m: 120,

};
↓ Note the v parameter
const phcstr = "$argon2i$v=19$m=120,t=5000,p=2$iHSDPHzUhPzK7rCcJgOFfg$J4moa2MM0/6uf3HbY2Tf5Fux8JIBTwIhmhxGRbsY14qhTltQt+Vw3b7tcJNEbk8ium8AQfZeD4tabCnNqfkD1g";

@@ -134,33 +131,5 @@

phc.deserialize(phcstr);
// => throws an error since there are more than 4 fields (a field is one $)
phc.deserialize(phcstr, false);
// => phcobj
```
With the same philosophy you can even serialize/deserialize MCF formatted strings.
```js
const phc = require('@phc/format');
const phcobj = {
id: 'pbkdf2-sha256',
raw: '6400',
salt: Buffer.from('0ZrzXitFSGltTQnBWOsdAw', 'base64'),
hash: Buffer.from('Y11AchqV4b0sUisdZd0Xr97KWoymNE0LNNrnEgY4H9M', 'base64'),
};
const phcstr = "$pbkdf2-sha256$6400$0ZrzXitFSGltTQnBWOsdAw$Y11AchqV4b0sUisdZd0Xr97KWoymNE0LNNrnEgY4H9M";
phc.serialize(phcobj);
// => phcstr
phc.deserialize(phcstr);
// => throws an error since the second field (a field is one $) is not a valid
// params string
phc.deserialize(phcstr, false);
// => phcobj
```
## API

@@ -173,3 +142,3 @@

</dd>
<dt><a href="#deserialize">deserialize(phcstr, [strict])</a> ⇒ <code>Object</code></dt>
<dt><a href="#deserialize">deserialize(phcstr)</a> ⇒ <code>Object</code></dt>
<dd><p>Parses data from a PHC string.</p>

@@ -191,3 +160,3 @@ </dd>

| opts.id | <code>string</code> | Symbolic name for the function. |
| [opts.raw] | <code>string</code> | Additional raw data added after the identifier. It's here to support argon2 v parameter and to generate MCF formatted strings. |
| [opts.version] | <code>Number</code> | The version of the function. |
| [opts.params] | <code>Object</code> | Parameters of the function. |

@@ -199,3 +168,3 @@ | [opts.salt] | <code>Buffer</code> | The salt as a binary buffer. |

### deserialize(phcstr, [strict]) ⇒ <code>Object</code>
### deserialize(phcstr) ⇒ <code>Object</code>
Parses data from a PHC string.

@@ -206,8 +175,6 @@

| Param | Type | Default | Description |
| --- | --- | --- | --- |
| phcstr | <code>string</code> | | A PHC string to parse. |
| [strict] | <code>boolean</code> | <code>true</code> | If false does not throw an error if there is one filed not unrecognized. The content of the unrecognized filed will be stored in the raw property of the output object. This is useful to parse out of specs parameters like the 'v' present in the argon2 hash format or to parse MCF formatted strings. |
| Param | Type | Description |
| --- | --- | --- |
| phcstr | <code>string</code> | A PHC string to parse. |
## Contributing

@@ -214,0 +181,0 @@ Contributions are REALLY welcome and if you find a security flaw in this code, PLEASE [report it][new issue].

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