# materialized-group-auth

> materialize a group authentication database from ordered logs

Latest version **2.1.0** (published 2020-05-18) · bsd license · 0 weekly downloads

## Install

```sh
npm install materialized-group-auth
pnpm add materialized-group-auth
yarn add materialized-group-auth
bun add materialized-group-auth
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 2.1.0 |
| Published | 2020-05-18 |
| First published | 2019-04-27 |
| Weekly downloads | 0 |
| License | bsd |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 6 |
| Unpacked size | 37.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | substack |

## Links

- npm: https://www.npmjs.com/package/materialized-group-auth
- npm.io page: https://npm.io/package/materialized-group-auth

## Dependencies (6)

- [once](https://npm.io/package/once.md) ^1.4.0
- [pump](https://npm.io/package/pump.md) ^3.0.0
- [mutexify](https://npm.io/package/mutexify.md) ^1.2.0
- [through2](https://npm.io/package/through2.md) ^3.0.1
- [duplexify](https://npm.io/package/duplexify.md) ^4.0.0
- [collect-stream](https://npm.io/package/collect-stream.md) ^1.2.1

## Recent versions

- 2.1.0 (latest) — 2020-05-18
- 2.0.1 — 2020-05-18
- 2.0.0 — 2020-05-17
- 1.3.0 — 2020-05-17
- 1.2.1 — 2020-05-05
- 1.2.0 — 2020-05-01
- 1.1.3 — 2019-08-24
- 1.1.2 — 2019-06-02
- 1.1.1 — 2019-06-02
- 1.1.0 — 2019-06-02
- 1.0.2 — 2019-06-02
- 1.0.1 — 2019-04-28
- 1.0.0 — 2019-04-27

## README

# materialized-group-auth

materialize a group authentication database from ordered logs

# example

This example sets up an auth database.

In a real setting you would probably write the log messages to an append-only
log store such as hypercore.

``` js
var mauth = require('materialized-group-auth')
var db = require('level')('/tmp/auth.db')
var auth = mauth(db)

var minimist = require('minimist')
var argv = minimist(process.argv.slice(2))

if (argv._[0] === 'write') {
  var doc = {
    type: argv.type,
    key: argv.key,
    by: argv.by || null,
    flags: argv.flags ? String(argv.flags).split(',') : [],
    group: argv.group,
    id: argv.id
  }
  auth.batch([doc], function (err) {
    if (err) console.error(err)
  })
} else if (argv._[0] === 'groups') {
  auth.getGroups(function (err, groups) {
    if (err) return console.error(err)
    groups.forEach((group) => console.log(group))
  })
} else if (argv._[0] === 'members') {
  auth.getMembers(argv._[1], function (err, members) {
    if (err) return console.error(err)
    members.forEach((member) => console.log(member))
  })
} else if (argv._[0] === 'membership') {
  auth.getMembership(argv._[1], function (err, groups) {
    if (err) return console.error(err)
    groups.forEach((groups) => console.log(groups))
  })
}
```

```
$ node auth.js write --type=add --key=1000 \
  --group=@ --id=user0 --flags=admin
$ node auth.js write --type=add --key=1001 \
  --group=cool --id=user1 --flags=mod --by=user0
$ node auth.js write --type=add --key=1002 \
  --group=cool --id=user2 --by=user1
$ node auth.js groups
{ id: '@' }
{ id: 'cool' }
$ node auth.js members cool
{ id: 'user1', flags: [ 'mod' ], key: 1001 }
{ id: 'user2', flags: [], key: 1002 }
$ node auth.js members @
{ id: 'user0', flags: [ 'admin' ], key: 1000 }
```

# api

``` js
var mauth = require('materialized-group-auth')
```

## var auth = mauth(db)

Create an `auth` instance from a levelup instance `db`.

## auth.batch(docs, opts={}, cb)

Batch-insert an array of operations `docs`. All the operations in `docs` must be
valid for any records to be written.

When `opts.skip` is `true`, batches will always succeed and invalid operations
will be silently ignored. This is a good setting if you build materialized views
from log data from external sources such as gossip. Otherwise the batch size
would affect the final state if there are invalid records.

Each `doc` in the `docs` batch should be one of these types:

### add

* type: 'add'
* key - string to refer to a document from the log
* group - group string name
* id - user id string to add
* by - user added by this user id string
* flags - an array of string roles to set for the user

### remove

* type: 'remove'
* key - string to refer to a document from the log
* group - group string name
* id - user id string to add
* by - user removed by this user id string

If `by` is `null`, the operation will always succeed.

* Users who have a flag `'mod'` can add and remove users who are not mod/admin
* Users who have a flag `'admin'` can add and remove everyone

The group `@` is special: members of this group are allowed to administer any
other group. Inside the `@` group, mod/admin policies apply for adminsitration.

## auth.isMember({ group, id }, cb)

Determine whether a user `id` is a member of `group` as `cb(err, isMember)` for
a boolean `isMember`.

## auth.getFlags({ group, id }, cb)

Get the array of string flags as `cb(err, flags)` for an `id` in a `group`.

## var rstream = auth.getGroups(cb)

Return a list of all the groups in the database as `cb(err, groups)` or a
readable object stream `rstream` where each row is of the form:

* `row.id` - group name string

## var rstream = auth.getMembers(group, cb)

Return a list of all the members in a `group` as `cb(err, members)` or a
readable object stream `rstream` where each row is of the form:

* `row.id` - id string of the group user
* `row.flags` - flag strings for the given user
* `row.key` - key to refer to an original document

## var rstream = auth.getMembership(id, cb)

Return a list of all the groups that the user `id` is a member of as
`cb(err, groups)` or a readable object stream `rstream` where each row is of the
form:

* `row.id` - string name of the group
* `row.flags` - flag strings for the given user
* `row.key` - key to refer to an original document

## var rstream = auth.getMemberHistory(id, cb)

Return a list of the history of a member `id` as `cb(err, history)` or a
readable object stream `rstream` where each row is of the form:

* `row.key` - key of the document in the historical log
* `row.group` - group string name where the event occured

## var rstream = auth.getGroupHistory(group, cb)

Return a list of the history of a `group` as `cb(err, history)` or a readable
object stream `rstream` where each row is of the form:

* `row.id` - id of the user
* `row.key` - key of the document to look up from the historical log

## var rstream = auth.list(opts={}, cb)

Return a list of all the records in the database of the form:

* `row.id` - string name of the user
* `row.flags` - flag strings for the given user
* `row.key` - key to refer to an original document
* `row.group` - string name of the group

## auth.on('update', function (update) {})

This event is emitted for each object passed to `batch()` that was successfully
written. Batch objects that are determined to be no-ops will not be emitted.

## auth.on('skip', function (skip) {})

When `opts.skip` is true, this event emits each object passed to `batch()` that
was skipped over.

# license

BSD

# install

npm install materialized-group-auth

---
_Source: https://npm.io/package/materialized-group-auth · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
