1.0.4 • Published 5 years ago

bs-auth0-session v1.0.4

Weekly downloads
2
License
MIT
Repository
github
Last release
5 years ago

bs-auth0-session

npm

Source: https://github.com/mscharley/bs-auth0-session
Author: Matthew Scharley
Contributors: See contributors on GitHub
Bugs/Support: Github Issues
Copyright: 2018
License: MIT license
Status: Active

Synopsis

Session management for ReasonReact using Auth0 for login.

Usage

This is a rather long example, but it should be complete and functional.

/* Util.re */
[@bs.val] [@bs.scope ("window", "location")]
external locationOrigin: string = "origin";

let urlToString = url =>
  (
    switch (url.React.Router.path) {
    | [] => "/"
    | _ =>
      url.React.Router.path->Belt.List.reduce("", (a, b) => a ++ "/" ++ b)
    }
  )
  ++ (url.search != "" ? "?" ++ url.search : "")
  ++ (url.hash != "" ? "#" ++ url.hash : "");

/* Router.re */
open BsAuth0Session;

type page =
  | Home
  | Callback
  | Logout
  | Login;

type state = {
  page: option(page),
  returnUrl: string,
};

type action =
  | Navigate(option(page));

let routerFn: ReasonReact.Router.url => option(page) =
  fun
  | {path: []} => Some(Home)
  | {path: ["oauth", "callback"]} => Some(Callback)
  | {path: ["logout"]} => Some(Logout)
  | {path: ["login"]} => Some(Login)
  | _ => None;

let component = ReasonReact.reducerComponent("Router");

let make = _children => {
  let router = (url, {ReasonReact.send}) => url->routerFn->Navigate;

  {
    ...component,
    initialState: _ => {
      let initialUrl = ReasonReact.Router.dangerouslyGetInitialUrl();
      {
        page: initialUrl->routerFn,
        returnUrl: initialUrl->Util.urlToString,
      }
    },
    didMount: self => {
      let watcherId = ReasonReact.Router.watchUrl(self.handle(router));
      self.onUnmount(_ => ReasonReact.Router.unwatchUrl(watcherId));
    },
    reducer: (action, state) =>
      switch (action) {
      | Navigate(page) => Update({...state, page})
      },
    render: ({state: {page, returnUrl}}) =>
      <SessionContext.Provider
        domain="my-domain.au.auth0.com"
        clientId="dJ9HRAcoottSxYnYourClientIdHere"
        callbackUrl={Util.locationOrigin ++ "/oauth/callback"}>
          <SessionContext.LoggedOutConsumer>
            ...{
                pending =>
                  switch (page, pending) {
                  | (Some(Logout), _) =>
                    <LogoutPage returnUrl={Util.locationOrigin ++ "/"} /> /* !! Provided !! */
                  | (Some(Callback), _) =>
                    <CallbackPage /> /* !! Provided !! */
                  | (_, true) => <LoadingPage />
                  | (_, false) =>
                    <Button
                      onClick={
                        _ev => session->Session.doLogin(~returnUrl, ())
                      }>
                      {ReasonReact.string("Login")}
                    </Button>
                  }
              }
          </SessionContext.LoggedOutConsumer>
          <SessionContext.LoggedInConsumer>
            ...{
                _session =>
                  switch (page) {
                  | Some(Logout) => <LogoutPage returnUrl={Util.locationOrigin ++ "/"} /> /* !! Provided !! */
                  | Some(Home) => <HomePage />
                  | Some(Callback) => React.null
                  | Some(Login) =>
                    React.Router.push("/");
                    React.null;
                  | None => <NotFoundPage />
                  }
              }
          </SessionContext.LoggedInConsumer>
      </SessionContext.Provider>,
  }
}

There's a whole suite of Consumers for all sorts of use-cases. There is also SessionContext.Consumer which is your escape hatch which exposes the raw session data that this library tracks.

Check SessionContext.rei for more details on the available consumers.