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

@mumbler/ngx-mumbler-api

v0.8.0

Published

Angular client module for on-boarding, bonding, sending and receiving of mumbles

Downloads

608

Readme

NgxMumblerApi

Reference implementation of a client module using the mumbler system.

Requirements

You'll need Angular's core files in version 10 and the typescript library in (at least) version 2, e.g.:

{
  "dependencies": {
    "@angular/common": "^13.0.0",
	"@angular/core": "^13.0.0",
	"tslib": "^2.3.1"
  }
}

The "tslib" is pulled automatically via npm.

In case of Angular's version: A minor version should work as well but may require some minor adaptions.

Installation

Simply put the "ngx-mumbler-api" to your "dependencies" section within your package.json and run npm install.

Usage

The mumbler system basically knows four operations, on-boarding, bonding, sending and receiving. Each operation is described below including a code example. The used "Mumble(r)Service" must be included in your controller/service constructor, like:

public constructor(
    private readonly _mumblerService: MumblerService,
    private readonly _mumbleService: MumbleService
) {}

All subsequent examples uses those one or both of these injected services.

FYI Service distinction:

  • MumblerService: Access to methods used to interact with the mumbler system, like on-boarding & bonding
  • MumbleService: Access to methods used to interact with a single mumble message including sending a mumble

On-Boarding

In order to signup "on-boarding" your client application to the mumbler system, run the following code:

this._mumblerService.onboarding( mumblerNick ).subscribe( { complete: () => {

    // handle the complete case

} } );

The mumblerNick can be chosen freely and may be already used by someone else. The nick name does not identify a mumbler account rather than help the user recognize its contacts more easily.

Bonding

To allow another mumbler account to exchange information with your account the two mumbler accounts must be bonded. The bonding process is a multi-stage procedure. Start the procedure by creating bonding information, like:

this._mumblerService.initBonding().pipe(

    tap( ( response: BondingParameterModel ) => {

        console.log( StaticConversion.ConvertBufferToString( response.token ) );
        console.log( StaticConversion.ConvertBufferToBase64( response.totp ) );

    } )

).subscribe();

After the bonding initialization is successful, you'll receive two buffers, a bonding token, and a bonding key. Both can be easily converted into various string-based formats (e.g. Hex or Base64) using the StaticConversion class of the ngx-mumbler-api module.

In order to proceed with the bonding process you'll need to share those two information with your other mumbler user, e.g. via QR-code. Please be aware, that a bonding request is not valid indefinitely.

After sharing the two information a bonding can commence (on the bonding target):

this._mumblerService.commenceBonding( token, totp ).pipe(

    tap( ( mumblerId: string ) => {

        console.log( `Bonded with ${ mumblerId }` );

    } )

).subscribe();

A successful bonding returns the mumblerId of the bonded account. After this step the two mumblers (you and your bonding partner instance) can exchange information.

FYI: Successful bonding is always bi-directional (two-way): When you bond with another mumbler account and this account commences the bonding process you'll be bi-directional bonded! A separate vice-versa bonding process is not required.

Sending

Prerequisite: To send a mumble to another mumbler you'll need to be bonded with the recipient mumbler account.

A mumble can hold two types of communication data, simple text (a string) and one or multiple binary blobs (files).

A complete example of creating and sending a mumble:

this._mumbleService.createNewMumble(
    recipientMumblerId,     /* Recipients mumblerId (must be bonded) */
    content,                /* Your app based content, e.g. Text or Control-Command */
    files                   /* A list of Blobs, e.g. Image file */
).pipe(

    switchMap( ( mumble: Mumble ) => this._mumbleService.sendMumble( mumble ) )

).subscribe( {
    complete: () => {

        // Sending completed

    }
} );

Mumble Content

The content accepted by a mumbler must inherit from the abstract class AppsMessage. You can extend this base "content" class as you like but keep in mind, all additional fields must be serializable via JSON. An example of a content class:

import { AppsMessage } from 'ngx-mumbler-api';

export class VeryCoolAppMessage extends AppsMessage {

    public coolInfo1: number;
    public coolInfo2: string;

    /**
     * Initializes a new VeryCoolAppMessage class
     *
     * @param {number} coolInfo1            Optional: Something you need for your app (WON'T BE NOT ENCRPYTED)
     * @param {string} content              Mandatory: Contains the mandatory mumbled content (WILL BE MUMBLED => ENCRYPTED)
     * @param {string} coolInfo2            Optional: Something you need for your app (WON'T BE NOT ENCRPYTED)
     */
    public constructor(
        coolInfo1: number,
        coolInfo2: string,
        content: string
    ) {

        super( content );   // <= This content string will be automatically encrypted before sending and decrypted on receiveing

        this.coolInfo1 = coolInfo1;
        this.coolInfo2 = coolInfo2;

    }

}

The above example extends the basic AppsMessage with two additional fields ("coolInfo1" and "coolInfo2"). Those fields won't be mumbled (encrypted) on transport. But those can be necessary for your implementation, eg. to associate mumbles within a thread.

Mumble File(s)

A mumble can contain 0-n files in the form of Uint8Array(s). The createNewMumble method optionally accepts an array of Uint8Array-encoded binary blobs. There are lots of implementations on how to convert a (Dom-) File to a UInt8Array out there. The StaticConversion class provides mechanisms to help you convert a File/Blob into a Uint8Array:

private files: Array< Uint8Array > = new Array< Uint8Array >();

/*
...
*/

// "FileList" provided by, e.g.:
// <input #file type="file" (change)="addFiles( file.files )" ... />
public addFiles( files: FileList ): void {

        const observables: Array< Observable< Uint8Array > > = [];

        for ( let i: number = 0; i<files.length; i++ ) {

            observables.push( StaticConversion.ConvertFileToBuffer( files.item( i ) ) );

        }

        forkJoin( ...observables ).pipe(

            tap( ( results: Array< Uint8Array > ) => {

                this.files.push( ...results );  // <= No contain all files as Uint8Array(s)

            } )

        ).subscribe();

    }

Receiving

In order to receive mumbles you need to listen to the mumbler delegation service. When listening to the mumbler delegation service a WebSocket connection is opened, and a observable is returned. When a mumble is delegated into your mumbler account the observable will emit a next event in which you can store/process the mumble. The following example is a simple receiving-observable-pipeline:

this._mumbleService.listen().pipe(      // <= Only emits on new mumble delegation (or on error)

    switchMap( ( mumble: Mumble ) => forkJoin( [

        this._mumbleService.decryptMumbleContent( mumble ),     // <= decrypt content (e.g. "VeryCoolAppMessage")
        // eslint-disable-next-line @typescript-eslint/typedef
        ...mumble.transmitPayload.files.map( ( value, index ) => this._mumbleService.decryptMumbleFile( mumble, index ) )

    ] ) ),

    switchMap( ( content: [string, ...Array< Blob > ] ) => of( JSON.parse( content[ 0 ] ) as VeryCoolAppMessage ) ),

).subscribe();

First the listen() method is called which emits on delegation with a mumble object. The mumble is still encrypted. To decrypt the content you have to call decryptMumbleContent. In order to decrypt the file(s) as well you'll need to call decryptMumbleFile providing the index of the file you want to decrypt.

Finally, the decrypted content can now be casted into your custom "VeryCoolAppMessage" object.

About

Mumbler was born as an idealist idea to apply the principals of the "Briefgeheimnis" to the digital age. We are very low on budget and are currently solely founded through and legally constituted within the austrian-based startup company mumbler gmbh.

Further we're currently in the progress of setting up a Indiegogo campaign to help found the infrastructure costs. In the meantime it would be great if you could support our efforts by donating a couple of euros.

Support

Please support the project with your coding-, design-, brain-time and/or spread the word.

Of course operating the infrastructure is a big issue as well. It would be great if you could support us by donating a couple of euros:

Thank you very much and we'll hope you’re as excited as we are on the idea of bringing back the “Briefgeheimnis” to the digital age.

Code of conduct

Lust but not least please read the COC.md file for details on our code of conduct. Contributing to the mumbler initiative you implicitly agree to our code of conduct and the mumbler intention.

Further information

The module follows the idea of the mumble initiative and utilizes its specifications.

Mumbler Initiative - The idea

The goal of the Mumbler initiative is to resurrect the german law concept of the “Briefgeheimnis” which translates to secrecy of correspondence and is the basis for privacy of correspondence. For centuries opening and/or reading a correspondence which was intended for someone else was a criminal act, often punished by jail time. The french King Louis XV even declared the death penalty on breaking the "Briefgeheimnis" (with his edict on 25. Sep 1742).

Today it is a well-known fact that all digital correspondence is stored somewhere and is read, analyzed, profiled and last but not least profited off by many parties.

The Mumbler initiative is convinced that it should be of paramount importance to keep the information where it belongs:

Only in the hands of the communication parties themselves.

The Mumbler initiative was created to achieve exactly that. Analog letters have/had the "Briefgeheimnis", digital correspondence have Mumbler.

Further information can be found at mumbler initiative

Mumbler Initiative - Initiator

Mumbler was created and is currently operated by:

mumbler gmbh
Jakob-Haringer-Str. 1
5020 Salzburg

[email protected]