npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@liquicode/lib-user-storage

v0.2.0

Published

A storage engine for user objects. Tracks user identity, ownership, and permissions.

Downloads

5

Readme

lib-user-storage

(v0.2.0)

A storage engine for user objects. Tracks object identity, ownership, and permissions.

                                                                                          +--------------------------+
                                                                                          |      MongoProvider       |
                                                                                      ==> +--------------------------+
                                                                                     /    | Reads and writes objects |
+-----------------+      +------------------------+      +--------------------+     /     | to a MongoDB instance.   |
|   Application   |      |     StorageObject      |      |    UserStorage     |    /      +--------------------------+
+-----------------+ <==> +------------------------+ <==> +--------------------+ <==      
| Works with user |      | Combines user identity |      | Controls access    |    \     
| owned objects.  |      | with object identity.  |      | by user identity.  |     \     +--------------------------+
+-----------------+      +------------------------+      +--------------------+      \    |      JsonProvider        |
                                                                                      ==> +--------------------------+
                                                                                          | Reads and writes objects |
                                                                                          | to an in-memory array.   |
                                                                                          +--------------------------+

NOTE: This project supercedes the older project lib-managed-storage.

Overview

One of the primary and initial challenges of developing a user-facing system is that of implementating a storage mechanism which promotes the concept of user owned data. This can be privata data such as documents and images. This can also refer to data which is authored or attributed to the user such as a blog post or comment.

It is also a growing expectation among application users to be able to maintain private data (or data attributed to them), in addition to being able to share that data with other users within the same application.

This library offers a way for NodeJS applications to implement storage strategies which promote user ownership and the sharing of that data amongst other users of the same system.

This library does not provide any authentication mechanism. It assumes that, by the time its functions are being called, the application has already confirmed the identity of the user.

Getting Started

Install via NPM:

npm install @liquicode/lib-user-storage

Include the library in your source code:

const LIB_USER_STORAGE = require( '@liquicode/lib-user-storage' );

Create a new storage service:

let storage = LIB_USER_STORAGE.NewUserStorage(); // Defaults to an in-memory json array.

Store objects:

let Bob = { user_id: '[email protected]', user_role: 'user' };
new_doc = await storage.CreateOne( Bob, { name: 'About Me', text: 'I am a system user!' } );

Share objects:

await storage.Share( Bob, new_doc, null, null, true ); // Make public, share with everyone.

Simple Usage

const LIB_USER_STORAGE = require( '@liquicode/lib-user-storage' );

// Make some fake users to work with.
let Alice = { user_id: '[email protected]', user_role: 'admin' };
let Bob = { user_id: '[email protected]', user_role: 'user' };
let Eve = { user_id: '[email protected]', user_role: 'user' };

// Get the user storage.
let storage = LIB_USER_STORAGE.NewUserStorage(); // Defaults to an in-memory json array.

let doc = null;

// Alice creates a public document that anyone can read.
doc = await storage.CreateOne( Alice, { name: 'Public Document', text: 'This is a public document.' } );
await storage.Share( Alice, doc, null, null, true ); // Share this doc with everyone.

// Alice creates a restricted document that only specific users have read or write access to.
doc = await storage.CreateOne( Alice, { name: 'Internal Document', text: 'This is an internal document.' } );
await storage.Share( Alice, doc, null, Bob.user_id ); // Give read and write access to Bob.
await storage.Share( Alice, doc, Eve.user_id ); // Give read-only access to Eve.

// Alice creates a restricted document that only specific users have read or write access to.
doc = await storage.CreateOne( Alice, { name: 'Secret Document', text: 'This is a secret document.' } );
await storage.Share( Alice, doc, Bob.user_id ); // Give read-only access to Bob.

// Create some private documents for Bob.
doc = await storage.CreateOne( Bob, { name: 'My Document', text: 'This is my document.' } );
doc = await storage.CreateOne( Bob, { name: 'My Document 2', text: 'This is my other document.' } );

// Create a private document for Eve.
doc = await storage.CreateOne( Eve, { name: 'Evil Plans', text: 'Step 1: Take over the world.' } );

How It Works

When storing user data to a backend storage device (e.g. MongoDB, JSON files) this library appends and maintains a special "info" field to each stored object. The name of this "info" field is configurable and defaults to __info.

For example, when you store a simple object such as:

let thing = await storage.CreateOne( user, { foo: 'bar' } );

the stored representation (and the object returned to you) will look something like this:

thing = {
	foo: 'bar',
	__: {	// Every stored object contains special info in its '__' field.
		id = 'cda0f50e-84b4-4a4e-91f5-29f73a00ffbb',	// unique id for this object.
		created_at: '2022-06-30T03:45:24.415Z',			// Timestamp of when this object was created.
		updated_at: '2022-06-30T03:45:24.415Z',			// Timestamp of when this object was last updated.
		owner_id = "[email protected]",					// User Identifier (anything unique to the user).
		readers = [],									// Array of user ids that have read access.
		writers = [],									// Array of user ids that have write access.
		public = false,									// Flag to give everyone read access to this object.
	}
}

The library tracks and manages object identity, ownership information, sharing permissions, and modification timestamps for each object residing in storage. This information allows the library to control, via library function calls, which objects are available to the users calling the functions.

The library performs an authorization function allowing your application to easily allow users to have "ownership" of their application data and to be able to share it to other users in the system. Note that it is the responsibility of the larger application to ensure that the proper credentials are examined and that a user is whom s/he claims to be.

API Summary

To use this library, first install into your project with NPM:

npm install @liquicode/lib-user-storage

Then, include it into your application code like this:

const LIB_USER_STORAGE = require( '@liquicode/lib-user-storage' );

Library Functions

These function are available from the library itself (e.g. LIB_USER_STORAGE):

  • DefaultConfiguration () : Returns a default user storage configuration object.

  • NewUserStorage ( Configuration ) : Returns a UserStorage object that exports the rest of the functions below.

    • See the Configuration topic for a more information on configuration and using storage providers.
  • StorageAdministrator () : Returns a user object having the 'admin' user role. (alias: Administrator())

  • StorageSupervisor () : Returns a user object having the 'super' user role. (alias: Supervisor())

UserStorage Functions

See the UserStorage topic for a more in-depth discussion of UserStorage behaviors and functions.

  • Utility Functions

    • NewStorageObject ( Owner, Prototype )
    • GetStorageInfo ( StorageObject )
    • GetStorageData ( StorageObject )
    • UserCanShare ( User, StorageObject )
    • UserCanWrite ( User, StorageObject )
    • UserCanRead ( User, StorageObject )
  • Discovery Functions

    • Count ( User, Criteria )
    • FindOne ( User, Criteria )
    • FindMany ( User, Criteria )
  • Manipulation Functions

    • CreateOne ( User, Prototype )
    • WriteOne ( User, UserObject )
    • DeleteOne ( User, Criteria )
    • DeleteMany ( User, Criteria )
  • Sharing Functions

    • SetOwner ( User, OwnerID, Criteria )
    • SetSharing ( User, Criteria, Readers, Writers, MakePublic )
    • Share ( User, Reader, Writer, Criteria )
    • Unshare ( User, Reader, Writer, Criteria )

Notices

  • The JsonProvider implementation in this library was inspired in part by the project jsondbfs.
  • The JsonProvider implementation in this library was inspired in part by the project NeDB.
  • In dedication to my family, without whom, this work would not be possible.

Dependencies

  • uuid : Used by UserStorage and JsonProvider to generate unique identifiers.
  • mongodb : Used by the MongoProvider implementation.
  • json-criteria : Used to provide MongoDB-like query functionality.
  • babel-polyfill : A dependency of the json-criteria package.
  • lockfile : Used by JsonProvider when flushing in-memory objects to disk.

Project Links