Socket
Socket
Sign inDemoInstall

private

Package Overview
Dependencies
0
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.1.2 to 0.1.3

2

package.json

@@ -19,3 +19,3 @@ {

],
"version": "0.1.2",
"version": "0.1.3",
"homepage": "http://github.com/benjamn/private",

@@ -22,0 +22,0 @@ "repository": {

"use strict";
var defProp = Object.defineProperty || function(obj, name, desc) {
// Normal property assignment is the best we can do if
// Object.defineProperty is not available.
obj[name] = desc.value;
// Normal property assignment is the best we can do if
// Object.defineProperty is not available.
obj[name] = desc.value;
};

@@ -15,5 +15,5 @@

function makeSafeToCall(fun) {
defProp(fun, "call", { value: fun.call });
defProp(fun, "apply", { value: fun.apply });
return fun;
defProp(fun, "call", { value: fun.call });
defProp(fun, "apply", { value: fun.apply });
return fun;
}

@@ -27,13 +27,13 @@

var create = Object.create || function(prototype, properties) {
cloner.prototype = prototype || null;
var obj = new cloner;
cloner.prototype = prototype || null;
var obj = new cloner;
// The properties parameter is unused by this module, but I want this
// shim to be as complete as possible.
if (properties)
for (var name in properties)
if (hasOwn.call(properties, name))
defProp(obj, name, properties[name]);
// The properties parameter is unused by this module, but I want this
// shim to be as complete as possible.
if (properties)
for (var name in properties)
if (hasOwn.call(properties, name))
defProp(obj, name, properties[name]);
return obj;
return obj;
};

@@ -45,7 +45,7 @@

function makeUniqueKey() {
// Collisions are highly unlikely, but this module is in the business
// of making guarantees rather than safe bets.
do var uniqueKey = strSlice.call(numToStr.call(rand(), 36), 2);
while (hasOwn.call(uniqueKeys, uniqueKey));
return uniqueKeys[uniqueKey] = uniqueKey;
// Collisions are highly unlikely, but this module is in the business of
// making guarantees rather than safe bets.
do var uniqueKey = strSlice.call(numToStr.call(rand(), 36), 2);
while (hasOwn.call(uniqueKeys, uniqueKey));
return uniqueKeys[uniqueKey] = uniqueKey;
}

@@ -56,9 +56,9 @@

defProp(exports, "makeUniqueKey", {
value: makeUniqueKey
value: makeUniqueKey
});
function wrap(obj, value) {
var old = obj[value.name];
defProp(obj, value.name, { value: value });
return old;
var old = obj[value.name];
defProp(obj, value.name, { value: value });
return old;
}

@@ -70,60 +70,61 @@

var realGetOPNs = wrap(Object, function getOwnPropertyNames(object) {
for (var names = realGetOPNs(object),
src = 0,
dst = 0,
len = names.length;
src < len;
++src) {
if (!hasOwn.call(uniqueKeys, names[src])) {
if (src > dst) {
names[dst] = names[src];
}
++dst;
}
for (var names = realGetOPNs(object),
src = 0,
dst = 0,
len = names.length;
src < len;
++src) {
if (!hasOwn.call(uniqueKeys, names[src])) {
if (src > dst) {
names[dst] = names[src];
}
++dst;
}
names.length = dst;
return names;
}
names.length = dst;
return names;
});
function defaultCreatorFn(object) {
return create(null);
return create(null);
}
function makeAccessor(secretCreatorFn) {
var brand = makeUniqueKey();
var passkey = create(null);
var brand = makeUniqueKey();
var passkey = create(null);
secretCreatorFn = secretCreatorFn || defaultCreatorFn;
secretCreatorFn = secretCreatorFn || defaultCreatorFn;
function register(object) {
var secret; // Created lazily.
defProp(object, brand, {
value: function(key, forget) {
// Only code that has access to the passkey can retrieve
// (or forget) the secret object.
if (key === passkey) {
return forget
? secret = null
: secret || (secret = secretCreatorFn(object));
}
}
});
}
function register(object) {
var secret; // Created lazily.
function accessor(object) {
if (!hasOwn.call(object, brand))
register(object);
return object[brand](passkey);
function vault(key, forget) {
// Only code that has access to the passkey can retrieve (or forget)
// the secret object.
if (key === passkey) {
return forget
? secret = null
: secret || (secret = secretCreatorFn(object));
}
}
accessor.forget = function(object) {
if (hasOwn.call(object, brand))
object[brand](passkey, true);
};
defProp(object, brand, { value: vault });
}
return accessor;
function accessor(object) {
if (!hasOwn.call(object, brand))
register(object);
return object[brand](passkey);
}
accessor.forget = function(object) {
if (hasOwn.call(object, brand))
object[brand](passkey, true);
};
return accessor;
}
defProp(exports, "makeAccessor", {
value: makeAccessor
value: makeAccessor
});

@@ -20,5 +20,51 @@ private [![Build Status](https://travis-ci.org/benjamn/private.png?branch=master)](https://travis-ci.org/benjamn/private)

Introduction
Usage
---
**Get or create a secret object associated with any (non-frozen) object:**
```js
var getSecret = require("private").makeAccessor();
var obj = Object.create(null); // any kind of object works
getSecret(obj).totallySafeProperty = "p455w0rd";
console.log(Object.keys(obj)); // []
console.log(Object.getOwnPropertyNames(obj)); // []
console.log(getSecret(obj)); // { totallySafeProperty: "p455w0rd" }
```
Now, only code that has a reference to both `getSecret` and `obj` can possibly access `.totallySafeProperty`.
*Importantly, no global references to the secret object are retained by the `private` package, so as soon as `obj` gets garbage collected, the secret will be reclaimed as well. In other words, you don't have to worry about memory leaks.*
**Create a unique property name that cannot be enumerated or guessed:**
```js
var secretKey = require("private").makeUniqueKey();
var obj = Object.create(null); // any kind of object works
Object.defineProperty(obj, secretKey, {
value: { totallySafeProperty: "p455w0rd" },
enumerable: false // optional; non-enumerability is the default
});
Object.defineProperty(obj, "nonEnumerableProperty", {
value: "anyone can guess my name",
enumerable: false
});
console.log(obj[secretKey].totallySafeProperty); // p455w0rd
console.log(obj.nonEnumerableProperty); // "anyone can guess my name"
console.log(Object.keys(obj)); // []
console.log(Object.getOwnPropertyNames(obj)); // ["nonEnumerableProperty"]
for (var key in obj) {
console.log(key); // never called
}
```
Because these keys are non-enumerable, you can't discover them using a `for`-`in` loop. Because `secretKey` is a long string of random characters, you would have a lot of trouble guessing it. And because the `private` module wraps `Object.getOwnPropertyNames` to exclude the keys it generates, you can't even use that interface to discover it.
Unless you have access to the value of the `secretKey` property name, there is no way to access the value associated with it. So your only responsibility as secret-keeper is to avoid handing out the value of `secretKey` to untrusted code.
Think of this style as a home-grown version of the first style. Note, however, that it requires a full implementation of ES5's `Object.defineProperty` method in order to make any safety guarantees, whereas the first example will provide safety even in environments that do not support `Object.defineProperty`.
Rationale
---
In JavaScript, the only data that are truly private are local variables

@@ -25,0 +71,0 @@ whose values do not *leak* from the scope in which they were defined.

@@ -21,6 +21,6 @@ var assert = require("assert");

try {
acc1(42);
throw new Error("threw wrong error");
acc1(42);
throw new Error("threw wrong error");
} catch (err) {
assert.ok(err);
assert.ok(err);
}

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

function creatorFn(object) {
return { self: object };
return { self: object };
}

@@ -59,4 +59,4 @@

assert.deepEqual(acc3(obj), {
self: obj,
xxx: "yyy"
self: obj,
xxx: "yyy"
});

@@ -66,3 +66,3 @@

assert.deepEqual(acc3(obj), {
self: obj
self: obj
});

@@ -69,0 +69,0 @@

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc