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

@forge4flow/forge4flow-react

v0.0.5

Published

React components for Forge4Flow

Downloads

25

Readme

@forge4flow/forge4flow-react

npm

Overview

The Forge4Flow React library provides components, hooks, and helper methods for controlling access to pages and components in React using Forge4Flow. The library interacts directly with the Forge4Flow-Core API using short-lived session tokens that can be created server-side using your API key or using the built in Authentication methods.

Installation

Use npm to install @forge4flow/forge4flow-react:

npm install @forge4flow/forge4flow-react

Usage

Forge4FlowProvider

Wrap your application with Forge4FlowProvider, passing it your Client Key and API Endpoint. Forge4FlowProvider uses React Context to allow you to access utility methods for performing access checks anywhere in your app.

// App.jsx
import React from "react";
import { Forge4FlowProvider } from "@forge4flow/forge4flow-react";

const App = () => {
  return (
    <Forge4FlowProvider
      clientKey="client_test_f5dsKVeYnVSLHGje44zAygqgqXiLJBICbFzCiAg1E="
      endpoint="https://your_api_endpoint.com"
    >
      {/* Routes, ThemeProviders, etc. */}
    </Forge4FlowProvider>
  );
};

export default App;

Authentication

Once your application has been wrapped with Forge4FlowProvider you can simple call add the useForge4Flow hook then call the authenticate method.

import { useForge4Flow } from "@forge4flow/forge4flow-nextjs";

const auth = useForge4Flow();

const handleLogin = async () => {
  const login = await auth.authenticate();

  if (login) {
    router.push("/admin");
  }
};

check

check is a utility function that returns a Promise which resolves with true if the user for the current session token has the specified relation on the specified object and returns false otherwise. Use it for fine-grained conditional rendering or for specific logic within components.

Using check through the useForge4Flow hook:

import React, { useEffect } from "react";
import { useForge4Flow } from "@forge4flow/forge4flow-react";

const MyComponent = () => {
  const { check } = useForge4Flow();

  useEffect(() => {
    const fetchProtectedInfo = async () => {
      // Only fetch protected info from server if
      // user can "view" the info object "protected_info".
      const userIsAuthorized = await check({
        object: {
          objectType: "info",
          objectId: "protected_info",
        },
        relation: "viewer",
      });
      if (userIsAuthorized) {
        // request protected info from server
      }
    };

    fetchProtectedInfo();
  });

  return (
    <div>{protectedInfo && <ProtectedInfo>{protectedInfo}</ProtectedInfo>}</div>
  );
};

export default MyComponent;

Or using the React Context API:

import React, { useEffect } from "react";
import { Forge4FlowContext } from "@forge4flow/forge4flow-react";

class MyComponent extends React.Component {
  async componentDidMount() {
    const { check } = this.context;

    // Only fetch protected info from server if
    // user can "view" the info object "protected_info".
    const userIsAuthorized = await check({
      object: {
        objectType: "info",
        objectId: "protected_info",
      },
      relation: "viewer",
    });
    if (userIsAuthorized) {
      await fetchProtectedInfo();
    }
  }

  async fetchProtectedInfo() {
    // request protected info from server
  }

  render() {
    return (
      <div>
        {protectedInfo && <ProtectedInfo>{protectedInfo}</ProtectedInfo>}
      </div>
    );
  }
}

MyComponent.contextType = Forge4FlowContext;

export default MyComponent;

checkMany

checkMany is a utility function that returns a Promise which resolves with true if the user for the current session token has all of or any of (based on a specified op) a set of specified warrants and returns false otherwise.

import { CheckOp } from "@forge4flow/forge4flow-js";

const { checkMany } = useForge4Flow();

// userIsAuthorized will only be true if the user is
// a member of tenant-A AND has permission view-protected-info
const userIsAuthorized = await checkMany({
  op: CheckOp.AllOf,
  warrants: [
    {
      object: {
        objectType: "tenant",
        objectId: "tenant-A",
      },
      relation: "member",
    },
    {
      object: {
        objectType: "permission",
        objectId: "view-protected-info",
      },
      relation: "member",
    },
  ],
});

hasPermission

hasPermission is a utility function that returns a Promise which resolves with true if the user for the current session token has the specified permissionId and returns false otherwise.

import { CheckOp } from "@forge4flow/forge4flow-js";

const { hasPermission } = useForge4Flow();

// userHasPermission will only be true if the user
// has the permission view-protected-info
const userHasPermission = await hasPermission({
  permissionId: "view-protected-info",
});

hasFeature

hasFeature is a utility function that returns a Promise which resolves with true if the user for the current session token has the specified featureId and returns false otherwise.

import { CheckOp } from "@forge4flow/forge4flow-js";

const { hasFeature } = useForge4Flow();

// userHasFeature will only be true if the user
// has the feature protected-info
const userHasFeature = await hasFeature({
  featureId: "protected-info",
});

ProtectedComponent

ProtectedComponent is a utility component you can wrap around markup or components that should only be accessible to users with certain privileges. It only renders the components it wraps if the user has the given warrants.

import React from "react";
import { ProtectedComponent } from "@forge4flow/forge4flow-react";

const MyComponent = () => {
  return (
    <div>
      <MyPublicComponent />
      {/* hides MyProtectedComponent unless the user can "view" myObject with id object.id */}
      <ProtectedComponent
        warrants={[
          {
            object: {
              objectType: "myObject",
              objectId: object.id,
            },
            relation: "view",
          },
        ]}
      >
        <MyProtectedComponent />
      </ProtectedComponent>
    </div>
  );
};

export default MyComponent;

PermissionProtectedComponent

PermissionProtectedComponent is a utility component you can wrap around markup or components that should only be accessible to users with certain privileges. It only renders the components it wraps if the user has the given permission.

import React from "react";
import { PermissionProtectedComponent } from "@forge4flow/forge4flow-react";

const MyComponent = () => {
  return (
    <div>
      <MyPublicComponent />
      {/* hides MyProtectedComponent unless the user has permission "view-protected-info" */}
      <PermissionProtectedComponent permissionId="view-protected-info">
        <MyProtectedComponent />
      </PermissionProtectedComponent>
    </div>
  );
};

export default MyComponent;

FeatureProtectedComponent

FeatureProtectedComponent is a utility component you can wrap around markup or components that should only be accessible to users with certain privileges. It only renders the components it wraps if the user has the given feature.

import React from "react";
import { FeatureProtectedComponent } from "@forge4flow/forge4flow-react";

const MyComponent = () => {
  return (
    <div>
      <MyPublicComponent />
      {/* hides MyProtectedComponent unless the user has feature "protected-info" */}
      <FeatureProtectedComponent featureId="protected-info">
        <MyProtectedComponent />
      </FeatureProtectedComponent>
    </div>
  );
};

export default MyComponent;

withForge4FlowCheck

Use the withForge4FlowCheck Higher Order Component (HOC) to protect components that should only be accessible to users with certain privileges.

Protecting Routes

NOTE: This example uses react-router but you can use any routing library.

// App.jsx
import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import { createBrowserHistory } from "history";
import { Forge4FlowProvider, withForge4FlowCheck } from "@forge4flow/forge4flow-react";
import PublicPage from "./PublicPage";
import ProtectedPage from "./ProtectedPage";

const history = createBrowserHistory();

const App = () => {
    return <Forge4FlowProvider clientKey="client_test_f5dsKVeYnVSLHGje44zAygqgqXiLJBICbFzCiAg1E=">
        <Router history={history}>
            <Switch>
                <Route path="/public_route" exact component={PublicPage}/>
                {/*
                    Only render ProtectedPage if the user
                    can "view" the route "protected_route".
                */}
                <Route path="/protected_route" exact component={withForge4FlowCheck(ProtectedPage, {
                    warrants: [{
                        object: {
                            objectType: "route",
                            objectId: "protected_route",
                        },
                        relation: "view",
                    }],
                    redirectTo: "/public_route",
                })}>
            </Switch>
        </Router>
    </Forge4FlowProvider>;
};

export default App;

Protecting Components

import React from "react";
import { withForge4FlowCheck } from "@forge4flow/forge4flow-react";

const MySecretComponent = () => {
  return <div>Super secret text</div>;
};

// Only render MySecretComponent if the user
// can "view" the component "MySecretComponent".
export default withForge4FlowCheck(MySecretComponent, {
  warrants: [
    {
      object: {
        objectType: "component",
        objectId: "MySecretComponent",
      },
      relation: "view",
    },
  ],
  redirectTo: "/",
});

withPermissionCheck

Use the withPermissionCheck Higher Order Component (HOC) to protect components that should only be accessible to users with a certain permission.

Protecting Routes

NOTE: This example uses react-router but you can use any routing library.

// App.jsx
import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import { createBrowserHistory } from "history";
import { Forge4FlowProvider, withPermissionCheck } from "@forge4flow/forge4flow-react";
import PublicPage from "./PublicPage";
import ProtectedPage from "./ProtectedPage";

const history = createBrowserHistory();

const App = () => {
    return <Forge4FlowProvider clientKey="client_test_f5dsKVeYnVSLHGje44zAygqgqXiLJBICbFzCiAg1E=">
        <Router history={history}>
            <Switch>
                <Route path="/public_route" exact component={PublicPage}/>
                {/*
                    Only render ProtectedPage if the user
                    has the "view-protected-route" permission.
                */}
                <Route path="/protected_route" exact component={withPermissionCheck(ProtectedPage, {
                    permissionId: "view-protected-route",
                    redirectTo: "/public_route",
                })}>
            </Switch>
        </Router>
    </Forge4FlowProvider>;
};

export default App;

Protecting Components

import React from "react";
import { withPermissionCheck } from "@forge4flow/forge4flow-react";

const MySecretComponent = () => {
  return <div>Super secret text</div>;
};

// Only render MySecretComponent if the user
// has the "view-protected-route" permission.
export default withPermissionCheck(MySecretComponent, {
  permissionId: "view-protected-route",
  redirectTo: "/",
});

withFeatureCheck

Use the withFeatureCheck Higher Order Component (HOC) to protect components that should only be accessible to users with a certain feature.

Protecting Routes

NOTE: This example uses react-router but you can use any routing library.

// App.jsx
import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import { createBrowserHistory } from "history";
import { Forge4FlowProvider, withFeatureCheck } from "@forge4flow/forge4flow-react";
import PublicPage from "./PublicPage";
import ProtectedPage from "./ProtectedPage";

const history = createBrowserHistory();

const App = () => {
    return <Forge4FlowProvider clientKey="client_test_f5dsKVeYnVSLHGje44zAygqgqXiLJBICbFzCiAg1E=">
        <Router history={history}>
            <Switch>
                <Route path="/public_route" exact component={PublicPage}/>
                {/*
                    Only render ProtectedPage if the user
                    has the "protected-route" feature.
                */}
                <Route path="/protected_route" exact component={withFeatureCheck(ProtectedPage, {
                    featureId: "protected-route",
                    redirectTo: "/public_route",
                })}>
            </Switch>
        </Router>
    </Forge4FlowProvider>;
};

export default App;

Protecting Components

import React from "react";
import { withFeatureCheck } from "@forge4flow/forge4flow-react";

const MySecretComponent = () => {
  return <div>Super secret text</div>;
};

// Only render MySecretComponent if the user
// has the "protected-route" feature.
export default withFeatureCheck(MySecretComponent, {
  featureId: "protected-route",
  redirectTo: "/",
});