Skip to content

Commit

Permalink
Minimal routing, required to handle callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
RawToast committed Mar 31, 2018
1 parent ae449ee commit fe04862
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 16 deletions.
32 changes: 27 additions & 5 deletions dokusho/src/App.re
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,41 @@
[%bs.raw {|require('../node_modules/auth0-js/build/auth0.js')|}];
[%bs.raw {|require('./toolbox/theme.css')|}];

open Dokusho;

[@bs.module]
external theme : ReactToolbox.ThemeProvider.theme = "./toolbox/theme";

let component = ReasonReact.statelessComponent("App");
open Dokusho;
open Types;

type action =
| ChangeRoute(Routes.route);

let reducer = (action, _state) =>
switch action {
| ChangeRoute(route) => ReasonReact.Update( route )
};

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

let make = _children => {
...component,
render: _self =>
reducer,
initialState: () => { Routes.Home },
render: self =>
<ReactToolbox.ThemeProvider theme>
<div className="app">
<Dokusho/>
(switch self.state {
| Routes.Home => <Dokusho/>
})
</div>
</ReactToolbox.ThemeProvider>
};

let mapUrlToRoute = (url: ReasonReact.Router.url) =>
switch url.path {
| [] => Routes.Home
| ["callback"] => {
LoginButton.Auth.handleAuth(url);
}
| _ => Routes.Home /* Routes.NotFound */
};
2 changes: 1 addition & 1 deletion dokusho/src/app/Dokusho.re
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ open Rationale;
module Dokusho {
let component = ReasonReact.reducerComponent("Dokusho");
let initState = () => {
readingData: { days : [Day.now()] },
readingData: { days : [ Day.now() ] },
selectedEntry: Book,
selectedDate: Js.Date.make()
};
Expand Down
59 changes: 49 additions & 10 deletions dokusho/src/app/LoginButton.re
Original file line number Diff line number Diff line change
@@ -1,18 +1,57 @@
module Auth {
type generatedAuth0Client = {.
"authorize": [@bs.meth] (unit => unit)
type generatedAuth0Client = {.
"authorize": [@bs.meth] (unit => unit)
};

type clientOptions = {
.
"domain": string,
"clientID": string,
"redirectUri": string,
"responseType": string,
"scope": string
};

type clientOptions = {
.
"domain": string,
"clientID": string,
"redirectUri": string,
"responseType": string,
"scope": string
[@bs.module "auth0-js"] [@bs.new] external createClient : (clientOptions => generatedAuth0Client) = "WebAuth";

let matchAccessToken = [%re "/access_token=([^\$&]+)/g"];
let matchExpiresIn = [%re "/expires_in=([^\$&]+)/g"];
let matchIdToken = [%re "/id_token=([^\$&]+)/g"];

let resolveOption = (opt) => switch opt {
| None => ""
| Some(s) => s
};

let resolveRegex = (exp, str) => {
let res = exp |> Js.Re.exec(str);
switch res {
| None => ""
| Some(result) => {
let captures = result |> Js.Re.captures;
switch captures {
| [|_, token|] => token |> Js.Nullable.to_opt |> resolveOption
| _ => ""
};
}};
};

open Types;
open Dom.Storage;

let handleAuth = (url: ReasonReact.Router.url) => {
let accessToken = url.hash |> resolveRegex(matchAccessToken);
let idToken = url.hash |> resolveRegex(matchIdToken);
let expiresIn = url.hash |> resolveRegex(matchExpiresIn);
localStorage |> setItem("accessToken", accessToken);
localStorage |> setItem("id_token", idToken);
localStorage |> setItem("expiresIn", expiresIn);

Routes.Home;
};

let getIdToken = () => localStorage |> getItem("id_token") |> resolveOption;

[@bs.module "auth0-js"] [@bs.new] external createClient : (clientOptions => generatedAuth0Client) = "WebAuth";
};

let authOptions = {
Expand Down
25 changes: 25 additions & 0 deletions dokusho/src/app/Types.re
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
/* TODO: Remove this for real authentication */
let testUser = "fully";

module Routes {
type route =
| Home;
};

type pageType =
| Manga
| News
Expand Down Expand Up @@ -39,7 +44,19 @@ type action =
| LoadUserData(string)
| SelectDate(Js.Date.t);

type authData = {
accessToken: string,
idToken: string,
expiresIn: string
};

module Decoders = {
let parseAuthData = (json: Js.Json.t) : authData =>
Json.Decode.{
accessToken: json |> field("accessToken", string),
idToken: json |> field("idToken", string),
expiresIn: json |> field("expiresIn", string)
};
let parsePageType = (asString:string) => {
switch (asString) {
| "Manga" => Manga
Expand Down Expand Up @@ -68,6 +85,14 @@ module Decoders = {
};

module Encoders = {
let encodeAuthData = authData =>
Json.Encode.(
object_([
("accessToken", string(authData.accessToken)),
("idToken", string(authData.idToken)),
("expiresIn", string(authData.expiresIn))
])
);
let encodeEntry = entry =>
Json.Encode.(
object_([
Expand Down

0 comments on commit fe04862

Please sign in to comment.