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

@novuminsights/unlock-protocol-firebase

v0.1.0

Published

Simple integration of Firebase authentication and authorization with Unlock locks

Downloads

14

Readme


description: >- This package allows Web3 enabled browsers the authenticate with Firebase. Access roles are assigned based on the wallet's locks.

README

Installation

Functions needed for cloud functions and in the browser are available via npm , browser capability can also be enabled via CDN for those not using a bundler.

{% tabs %} {% tab title="Node.js" %}

$ npm i @novum/unlock-firebase-integration

{% endtab %}

{% tab title="CDN" %}

<script type="text/javascript"
    src="https://unpkg.com/@novuminsights/unlock-protocol-firebase/lib/browser.js"></script>

{% endtab %} {% endtabs %}

Authentication

This package allows wallet holders to login to Firebase Authentication by verifying wallet ownership via signed message. No additional information is required. If you are using other authentication providers, I'd recommend merging user created in this way and using AccountClaimReader in @novum/unlock-firebase-integration/server/helpers to maintain user claims in a customer manner.

Enabling Cloud Function authentication with for Wallet Users

That's all you need for the backend:

{% code title="functions/src/index.js" %}

//initialize you app as you normally would
import * as admin from "firebase-admin";
admin.initializeApp();

//expose getLockFirebaseToken and createMessageToken as you would any other function
export {getLockFirebaseToken, createMessageToken} from "@novuminsights/unlock-protocol-firebase/lib/server";

{% endcode %}

On the frond end, just call signInWithWeb3. For example using a button:

{% tabs %} {% tab title="Bundler" %}

import "firebase/auth"
import "firebase/functions"
import {signInWithWeb3} from '@novum/unlock-firebase-integration/lib/browser'

const app = firebase.initializeApp(firebaseConfig);
const signInButton = document.querySelector('#MyButton')
signInButton.onclick = () => signInWithWeb3(app);

{% endtab %}

{% tab title="CDN" %}

<script src="https://www.gstatic.com/firebasejs/8.8.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.8.1/firebase-functions.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.8.1/firebase-auth.js"></script>
<script type="text/javascript"
    src="https://unpkg.com/@novuminsights/unlock-protocol-firebase/lib/browser.js"></script>
....
<script>
    const app = firebase.initializeApp(firebaseConfig);
    const signInButton = document.querySelector('#MyButton')
    signInButton.onclick = async () => {
        await unlockProtocolFirebaseBrowser.signInWithWeb3(app)
    };
</script>

{% endtab %} {% endtabs %}

Controlling Access Through Locks

This integration uses the Unlock Protocol locks held in a wallet to assign access roles to Firebase users via Firebase's custom claims (assessed on login).

Mapping locks to roles

Custom claims are assigned to the user upon authentication based on the locks the wallet currently has. The mapping from lock addresses to claims is defined in unlock-integration-config.json, like so:

{% code title="functions/unlock-integration.config.json" %}

{
    "networks": {
        "mainnet": {
            "provider_url": "https://mainnet.infura.io/v3/678543fed855441b7b642730944ee4469",
            "locks": {
                "0x361Ddf540e27632D80dDE806EAa76AC42A0e15F6": ["basic_subscription"]
            }
        },
        "rinkby": {}
    },
  "default_network": "mainnet",
  "default_claims": ["wallet_owner"]
}

{% endcode %}

You can define multiple networks, but currently only one network is used at a time. You can set which network will be used for a particular project via firebase functions config like so:

firebase functions:config:set unlock.network=rinkby

Otherwise, default_network as defined in unlock-integration-config.json is used. This is useful for testing with rinkby. Support for multiple active networks can be added in the future.

Using claims for role-based access

You can access these claims directly from the user's token --- for example, in your firestore rules:

{% code title="firestore.rules" %}

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
      match /{document=**} {
      allow read, write: if false;
    }
    function hasSubscription() {
      return request.auth != null && request.auth.token.basic_subcriptionic_sub;
    }
    match /app_data/top_pairs {
          allow read: if hasSubscription();
    }
}

{% endcode %}

As well as, your Firebase functions:

async function hasBasicSubscription(context) {
    const auth = context.auth;
    ...
    return auth.token.basic_subscription === true;
}

or in the browser:

export async function canViewDashboard(user) {
    const result = await user.getIdTokenResult(true);
    return (result.claims.basic_subscription === true);
}

Example Project