Node API attempt #1
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -253,7 +253,7 @@ paket-files/ | |||||||
| *.sln.iml | *.sln.iml | ||||||
| 
 | 
 | ||||||
| # Compiled files / application | # Compiled files / application | ||||||
| src/api/wwwroot/index.html | src/api/public/index.html | ||||||
| src/api/wwwroot/static | src/api/public/static | ||||||
| src/api/appsettings.json | src/api/appsettings.json | ||||||
| build/ | build/ | ||||||
							
								
								
									
										195
									
								
								src/api/App.fs
									
									
									
									
									
								
							
							
						
						
									
										195
									
								
								src/api/App.fs
									
									
									
									
									
								
							| @ -1,195 +0,0 @@ | |||||||
| /// Main server module for myPrayerJournal |  | ||||||
| module MyPrayerJournal.App |  | ||||||
| 
 |  | ||||||
| open Microsoft.EntityFrameworkCore |  | ||||||
| open Newtonsoft.Json |  | ||||||
| open Newtonsoft.Json.Linq |  | ||||||
| open System |  | ||||||
| open System.IO |  | ||||||
| open Suave |  | ||||||
| open Suave.Filters |  | ||||||
| open Suave.Operators |  | ||||||
| 
 |  | ||||||
| // --- Types --- |  | ||||||
| 
 |  | ||||||
| /// Auth0 settings |  | ||||||
| type Auth0Config = { |  | ||||||
|   /// The domain used with Auth0 |  | ||||||
|   Domain : string |  | ||||||
|   /// The client Id |  | ||||||
|   ClientId : string |  | ||||||
|   /// The base64-encoded client secret |  | ||||||
|   ClientSecret : string |  | ||||||
|   /// The URL-safe base64-encoded client secret |  | ||||||
|   ClientSecretJwt : string |  | ||||||
|   } |  | ||||||
| with |  | ||||||
|   /// An empty set of Auth0 settings |  | ||||||
|   static member empty = |  | ||||||
|     { Domain = "" |  | ||||||
|       ClientId = "" |  | ||||||
|       ClientSecret = "" |  | ||||||
|       ClientSecretJwt = "" |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
| /// Application configuration |  | ||||||
| type AppConfig = { |  | ||||||
|   /// PostgreSQL connection string |  | ||||||
|   Conn : string |  | ||||||
|   /// Auth0 settings |  | ||||||
|   Auth0 : Auth0Config |  | ||||||
|   } |  | ||||||
| with |  | ||||||
|   static member empty = |  | ||||||
|     { Conn = "" |  | ||||||
|       Auth0 = Auth0Config.empty |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
| /// A JSON response as a data property |  | ||||||
| type JsonOkResponse<'a> = { |  | ||||||
|   data : 'a |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
| /// A JSON response indicating an error occurred |  | ||||||
| type JsonErrorResponse = { |  | ||||||
|   error : string |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /// Configuration instances |  | ||||||
| module Config = |  | ||||||
|    |  | ||||||
|   /// Application configuration |  | ||||||
|   let app = |  | ||||||
|     try |  | ||||||
|       use sr = File.OpenText "appsettings.json" |  | ||||||
|       use tr = new JsonTextReader (sr) |  | ||||||
|       let settings = JToken.ReadFrom tr |  | ||||||
|       let secret = settings.["auth0"].["client-secret"].ToObject<string>() |  | ||||||
|       { Conn = settings.["conn"].ToObject<string>() |  | ||||||
|         Auth0 = |  | ||||||
|           { Domain = settings.["auth0"].["domain"].ToObject<string>() |  | ||||||
|             ClientId = settings.["auth0"].["client-id"].ToObject<string>() |  | ||||||
|             ClientSecret = secret |  | ||||||
|             ClientSecretJwt = secret.TrimEnd('=').Replace("-", "+").Replace("_", "/") |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     with _ -> AppConfig.empty |  | ||||||
| 
 |  | ||||||
|   /// Custom Suave configuration |  | ||||||
|   let suave = |  | ||||||
|     { defaultConfig with |  | ||||||
|         homeFolder = Some (Path.GetFullPath "./wwwroot/") |  | ||||||
|         serverKey = Text.Encoding.UTF8.GetBytes("12345678901234567890123456789012") |  | ||||||
|         bindings = [ HttpBinding.createSimple HTTP "127.0.0.1" 8084 ] |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /// Authorization functions |  | ||||||
| module Auth = |  | ||||||
| 
 |  | ||||||
|   /// Shorthand for Console.WriteLine |  | ||||||
|   let cw (x : string) = Console.WriteLine x |  | ||||||
| 
 |  | ||||||
|   /// Convert microtime to ticks, add difference from 1/1/1 to 1/1/1970 |  | ||||||
|   let jsDate jsTicks = |  | ||||||
|     DateTime(jsTicks * 10000000L).AddTicks(DateTime(1970, 1, 1).Ticks) |  | ||||||
|    |  | ||||||
|   /// Get the user Id (sub) from a JSON Web Token |  | ||||||
|   let getIdFromToken jwt = |  | ||||||
|     try |  | ||||||
|       let payload = Jose.JWT.Decode<JObject>(jwt, Config.app.Auth0.ClientSecretJwt) |  | ||||||
|       let tokenExpires = jsDate (payload.["exp"].ToObject<int64>()) |  | ||||||
|       match tokenExpires > DateTime.UtcNow with |  | ||||||
|       | true -> Some (payload.["sub"].ToObject<string>()) |  | ||||||
|       | _ -> None |  | ||||||
|     with ex -> |  | ||||||
|       sprintf "Token Deserialization Exception - %s" (ex.GetType().FullName) |> cw |  | ||||||
|       sprintf "Message - %s" ex.Message |> cw |  | ||||||
|       ex.StackTrace |> cw |  | ||||||
|       None |  | ||||||
|    |  | ||||||
|   /// Add the logged on user Id to the context if it exists |  | ||||||
|   let loggedOn = |  | ||||||
|     warbler (fun ctx -> |  | ||||||
|       match ctx.request.header "Authorization" with |  | ||||||
|       | Choice1Of2 bearer -> Writers.setUserData "user" (getIdFromToken <| bearer.Split(' ').[1]) |  | ||||||
|       | _ -> Writers.setUserData "user" None) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| // --- Support --- |  | ||||||
| 
 |  | ||||||
| /// Get the scheme, host, and port of the URL |  | ||||||
| let schemeHostPort (req : HttpRequest) = |  | ||||||
|   sprintf "%s://%s" req.url.Scheme (req.headers |> List.filter (fun x -> fst x = "host") |> List.head |> snd) |  | ||||||
| 
 |  | ||||||
| /// Serialize an object to JSON |  | ||||||
| let toJson = JsonConvert.SerializeObject |  | ||||||
| 
 |  | ||||||
| /// Read an item from the user state, downcast to the expected type |  | ||||||
| let read ctx key : 'value = |  | ||||||
|   ctx.userState |> Map.tryFind key |> Option.map (fun x -> x :?> 'value) |> Option.get |  | ||||||
| 
 |  | ||||||
| /// Create a new data context |  | ||||||
| let dataCtx () = |  | ||||||
|   new DataContext (((DbContextOptionsBuilder<DataContext>()).UseNpgsql Config.app.Conn).Options) |  | ||||||
| 
 |  | ||||||
| /// Ensure the EF context is created in the right format |  | ||||||
| let ensureDatabase () = |  | ||||||
|   async { |  | ||||||
|     use data = dataCtx () |  | ||||||
|     do! data.Database.MigrateAsync () |  | ||||||
|     } |  | ||||||
|   |> Async.RunSynchronously |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /// URL routes for myPrayerJournal |  | ||||||
| module Route = |  | ||||||
| 
 |  | ||||||
|   /// /api/journal ~ All active prayer requests for a user |  | ||||||
|   let journal = "/api/journal" |  | ||||||
| 
 |  | ||||||
| /// All WebParts that compose the public API |  | ||||||
| module WebParts = |  | ||||||
|    |  | ||||||
|   let jsonMimeType = |  | ||||||
|     warbler (fun ctx -> Writers.setMimeType "application/json; charset=utf8") |  | ||||||
| 
 |  | ||||||
|   /// WebPart to return a JSON response |  | ||||||
|   let JSON payload = |  | ||||||
|     jsonMimeType |  | ||||||
|     >=> Successful.OK (toJson { data = payload }) |  | ||||||
| 
 |  | ||||||
|   /// WebPart to return an JSON error response |  | ||||||
|   let errorJSON code error = |  | ||||||
|     jsonMimeType |  | ||||||
|     >=> Response.response code ((toJson >> Text.Encoding.UTF8.GetBytes) { error = error }) |  | ||||||
| 
 |  | ||||||
|   /// Journal page |  | ||||||
|   let viewJournal = |  | ||||||
|     context (fun ctx -> |  | ||||||
|       use dataCtx = dataCtx () |  | ||||||
|       let reqs = Data.Requests.allForUser (defaultArg (read ctx "user") "") dataCtx |  | ||||||
|       JSON reqs) |  | ||||||
| 
 |  | ||||||
|   /// API-specific routes |  | ||||||
|   let apiRoutes = |  | ||||||
|     choose [ |  | ||||||
|       GET >=> path Route.journal >=> viewJournal |  | ||||||
|       errorJSON HttpCode.HTTP_404 "Page not found" |  | ||||||
|       ] |  | ||||||
| 
 |  | ||||||
|   /// Suave application |  | ||||||
|   let app = |  | ||||||
|     Auth.loggedOn |  | ||||||
|     >=> choose [ |  | ||||||
|           path "/api" >=> apiRoutes |  | ||||||
|           Files.browseHome |  | ||||||
|           Files.browseFileHome "index.html" |  | ||||||
|           ] |  | ||||||
| 
 |  | ||||||
| [<EntryPoint>] |  | ||||||
| let main argv =  |  | ||||||
|   ensureDatabase () |  | ||||||
|   startWebServer Config.suave WebParts.app |  | ||||||
|   0  |  | ||||||
| @ -1,57 +0,0 @@ | |||||||
| namespace MyPrayerJournal |  | ||||||
| 
 |  | ||||||
| open Microsoft.EntityFrameworkCore |  | ||||||
| open System.Linq |  | ||||||
| open System.Runtime.CompilerServices |  | ||||||
| 
 |  | ||||||
| /// Data context for myPrayerJournal |  | ||||||
| type DataContext = |  | ||||||
|   inherit DbContext |  | ||||||
| 
 |  | ||||||
|   (*--- CONSTRUCTORS ---*) |  | ||||||
| 
 |  | ||||||
|   new () = { inherit DbContext () } |  | ||||||
|   new (options : DbContextOptions<DataContext>) = { inherit DbContext (options) } |  | ||||||
| 
 |  | ||||||
|   (*--- DbSet FIELDS ---*) |  | ||||||
| 
 |  | ||||||
|   [<DefaultValue>] |  | ||||||
|   val mutable private requests : DbSet<Request> |  | ||||||
|   [<DefaultValue>] |  | ||||||
|   val mutable private history : DbSet<History> |  | ||||||
|    |  | ||||||
|   (*--- DbSet PROPERTIES ---*) |  | ||||||
| 
 |  | ||||||
|   /// Prayer Requests |  | ||||||
|   member this.Requests with get () = this.requests and set v = this.requests <- v |  | ||||||
| 
 |  | ||||||
|   /// History |  | ||||||
|   member this.History with get () = this.history and set v = this.history <- v |  | ||||||
| 
 |  | ||||||
|   override this.OnModelCreating (modelBuilder) = |  | ||||||
|     base.OnModelCreating modelBuilder |  | ||||||
| 
 |  | ||||||
|     modelBuilder.HasDefaultSchema "mpj" |  | ||||||
|     |> Request.ConfigureEF |  | ||||||
|     |> History.ConfigureEF |  | ||||||
|     |> ignore |  | ||||||
| 
 |  | ||||||
| /// Data access |  | ||||||
| module Data = |  | ||||||
| 
 |  | ||||||
|   /// Data access for prayer requests |  | ||||||
|   module Requests = |  | ||||||
| 
 |  | ||||||
|     /// Get all prayer requests for a user |  | ||||||
|     let allForUser userId (ctx : DataContext) = |  | ||||||
|       query { |  | ||||||
|         for req in ctx.Requests do |  | ||||||
|           where (req.UserId = userId) |  | ||||||
|           select req |  | ||||||
|       } |  | ||||||
|       |> Seq.sortBy |  | ||||||
|         (fun req -> |  | ||||||
|           match req.History |> Seq.sortBy (fun hist -> hist.AsOf) |> Seq.tryLast with |  | ||||||
|           | Some hist -> hist.AsOf |  | ||||||
|           | _ -> 0L) |  | ||||||
|       |> List.ofSeq |  | ||||||
| @ -1,48 +0,0 @@ | |||||||
| namespace MyPrayerJournal |  | ||||||
| 
 |  | ||||||
| //open RethinkDb.Driver.Net |  | ||||||
| 
 |  | ||||||
| // -- begin code lifted from #er demo -- |  | ||||||
| type ReaderM<'d, 'out> = 'd -> 'out |  | ||||||
| 
 |  | ||||||
| module Reader = |  | ||||||
|   // basic operations |  | ||||||
|   let run dep (rm : ReaderM<_,_>) = rm dep |  | ||||||
|   let constant (c : 'c) : ReaderM<_,'c> = fun _ -> c |  | ||||||
|   // lifting of functions and state |  | ||||||
|   let lift1 (f : 'd -> 'a -> 'out) : 'a -> ReaderM<'d, 'out> = fun a dep -> f dep a |  | ||||||
|   let lift2 (f : 'd -> 'a -> 'b -> 'out) : 'a -> 'b -> ReaderM<'d, 'out> = fun a b dep -> f dep a b |  | ||||||
|   let lift3 (f : 'd -> 'a -> 'b -> 'c -> 'out) : 'a -> 'b -> 'c -> ReaderM<'d, 'out> = fun a b c dep -> f dep a b c |  | ||||||
|   let liftDep (proj : 'd2 -> 'd1) (rm : ReaderM<'d1, 'output>) : ReaderM<'d2, 'output> = proj >> rm |  | ||||||
|   // functor |  | ||||||
|   let fmap (f : 'a -> 'b) (g : 'c -> 'a) : ('c -> 'b) = g >> f |  | ||||||
|   let map (f : 'a -> 'b) (rm : ReaderM<'d, 'a>) : ReaderM<'d,'b> = rm >> f |  | ||||||
|   let (<?>) = map |  | ||||||
|   // applicative-functor |  | ||||||
|   let apply (f : ReaderM<'d, 'a->'b>) (rm : ReaderM<'d, 'a>) : ReaderM<'d, 'b> = |  | ||||||
|     fun dep -> |  | ||||||
|       let f' = run dep f |  | ||||||
|       let a  = run dep rm |  | ||||||
|       f' a |  | ||||||
|   let (<*>) = apply |  | ||||||
|   // monad |  | ||||||
|   let bind (rm : ReaderM<'d, 'a>) (f : 'a -> ReaderM<'d,'b>) : ReaderM<'d, 'b> = |  | ||||||
|     fun dep -> |  | ||||||
|       f (rm dep)  |  | ||||||
|       |> run dep  |  | ||||||
|   let (>>=) = bind |  | ||||||
|   type ReaderMBuilder internal () = |  | ||||||
|     member __.Bind(m, f)    = m >>= f |  | ||||||
|     member __.Return(v)     = constant v |  | ||||||
|     member __.ReturnFrom(v) = v |  | ||||||
|     member __.Delay(f)      = f () |  | ||||||
|   let reader = ReaderMBuilder() |  | ||||||
| // -- end code lifted from #er demo -- |  | ||||||
| 
 |  | ||||||
| (*type IDependencies = |  | ||||||
|   abstract Conn : IConnection |  | ||||||
| 
 |  | ||||||
| [<AutoOpen>] |  | ||||||
| module DependencyExtraction = |  | ||||||
|    |  | ||||||
|   let getConn (deps : IDependencies) = deps.Conn*) |  | ||||||
| @ -1,131 +0,0 @@ | |||||||
| namespace MyPrayerJournal |  | ||||||
| 
 |  | ||||||
| open Microsoft.EntityFrameworkCore; |  | ||||||
| open Newtonsoft.Json |  | ||||||
| open System |  | ||||||
| open System.Collections.Generic |  | ||||||
| 
 |  | ||||||
| /// A prayer request |  | ||||||
| [<AllowNullLiteral>] |  | ||||||
| type Request() = |  | ||||||
|   /// The history collection (can be overridden) |  | ||||||
|   let mutable historyCollection : ICollection<History> = upcast List<History> ()  |  | ||||||
|    |  | ||||||
|   /// The Id of the prayer request |  | ||||||
|   member val RequestId = Guid.Empty with get, set |  | ||||||
|   /// The Id of the user to whom the request belongs |  | ||||||
|   member val UserId = "" with get, set |  | ||||||
|   /// The ticks when the request was entered |  | ||||||
|   member val EnteredOn = 0L with get, set |  | ||||||
|    |  | ||||||
|   /// The history for the prayer request |  | ||||||
|   abstract History : ICollection<History> with get, set |  | ||||||
|   default this.History |  | ||||||
|     with get () = historyCollection |  | ||||||
|     and set v = historyCollection <- v |  | ||||||
|    |  | ||||||
|   static member ConfigureEF (mb : ModelBuilder) = |  | ||||||
|     mb.Entity<Request>().ToTable "Request" |  | ||||||
|     |> ignore |  | ||||||
|     mb |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /// A historial update to a prayer request |  | ||||||
| and [<AllowNullLiteral>] History() = |  | ||||||
|   /// The request to which this entry applies (may be overridden) |  | ||||||
|   let mutable request = null |  | ||||||
| 
 |  | ||||||
|   /// The Id of the request to which this update applies |  | ||||||
|   member val RequestId = Guid.Empty with get, set |  | ||||||
|   /// The ticks when this entry was made |  | ||||||
|   member val AsOf = 0L with get, set |  | ||||||
|   /// The status of the request as of this history entry |  | ||||||
|   member val Status = "" with get, set |  | ||||||
|   /// The text of this history entry |  | ||||||
|   member val Text = "" with get, set |  | ||||||
| 
 |  | ||||||
|   /// The request to which this entry belongs |  | ||||||
|   abstract Request : Request with get, set |  | ||||||
|   default this.Request  |  | ||||||
|     with get () = request |  | ||||||
|     and set v = request <- v |  | ||||||
| 
 |  | ||||||
|   static member ConfigureEF (mb : ModelBuilder) = |  | ||||||
|     mb.Entity<History>().ToTable("History") |  | ||||||
|     |> ignore |  | ||||||
|     mb.Entity<History>().HasKey(fun e -> (e.RequestId, e.AsOf) :> obj) |  | ||||||
|     |> ignore |  | ||||||
|     mb |  | ||||||
| 
 |  | ||||||
| (* |  | ||||||
| /// A user |  | ||||||
| type Userr = { |  | ||||||
|   /// The Id of the user |  | ||||||
|   [<JsonProperty("id")>] |  | ||||||
|   Id : string |  | ||||||
|   /// The user's e-mail address |  | ||||||
|   Email : string |  | ||||||
|   /// The user's name |  | ||||||
|   Name : string |  | ||||||
|   /// The time zone in which the user resides |  | ||||||
|   TimeZone : string |  | ||||||
|   /// The last time the user logged on |  | ||||||
|   LastSeenOn : int64 |  | ||||||
| } |  | ||||||
|   with |  | ||||||
|     /// An empty User |  | ||||||
|     static member Empty = |  | ||||||
|       { Id           = "" |  | ||||||
|         Email        = "" |  | ||||||
|         Name         = "" |  | ||||||
|         TimeZone     = "" |  | ||||||
|         LastSeenOn   = int64 0 } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| /// Request history entry |  | ||||||
| type Historyy = { |  | ||||||
|   /// The instant at which the update was made |  | ||||||
|   AsOf : int64 |  | ||||||
|   /// The action that was taken on the request |  | ||||||
|   Action : string list |  | ||||||
|   /// The status of the request (filled if it changed) |  | ||||||
|   Status : string option |  | ||||||
|   /// The text of the request (filled if it changed) |  | ||||||
|   Text : string option |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /// A prayer request |  | ||||||
| type Requestt = { |  | ||||||
|   /// The Id of the request |  | ||||||
|   [<JsonProperty("id")>] |  | ||||||
|   Id : string |  | ||||||
|   /// The Id of the user to whom this request belongs |  | ||||||
|   UserId : string |  | ||||||
|   /// The instant this request was entered |  | ||||||
|   EnteredOn : int64 |  | ||||||
|   /// The history for this request |  | ||||||
|   History : Historyy list |  | ||||||
| } |  | ||||||
|   with |  | ||||||
|     /// The current status of the prayer request |  | ||||||
|     member this.Status = |  | ||||||
|       this.History |  | ||||||
|       |> List.sortBy (fun item -> -item.AsOf) |  | ||||||
|       |> List.map    (fun item -> item.Status) |  | ||||||
|       |> List.filter Option.isSome |  | ||||||
|       |> List.map    Option.get |  | ||||||
|       |> List.head |  | ||||||
|     /// The current text of the prayer request |  | ||||||
|     member this.Text = |  | ||||||
|       this.History |  | ||||||
|       |> List.sortBy (fun item -> -item.AsOf) |  | ||||||
|       |> List.map    (fun item -> item.Text) |  | ||||||
|       |> List.filter Option.isSome |  | ||||||
|       |> List.map Option.get |  | ||||||
|       |> List.head |  | ||||||
|     member this.LastActionOn = |  | ||||||
|       this.History |  | ||||||
|       |> List.sortBy (fun item -> -item.AsOf) |  | ||||||
|       |> List.map    (fun item -> item.AsOf) |  | ||||||
|       |> List.head |  | ||||||
| *) |  | ||||||
| @ -1,16 +0,0 @@ | |||||||
| [<AutoOpen>] |  | ||||||
| module MyPrayerJournal.Extensions |  | ||||||
| 
 |  | ||||||
| open System.Threading.Tasks |  | ||||||
| 
 |  | ||||||
| // H/T: Suave |  | ||||||
| type AsyncBuilder with |  | ||||||
|   /// An extension method that overloads the standard 'Bind' of the 'async' builder. The new overload awaits on |  | ||||||
|   /// a standard .NET task |  | ||||||
|   member x.Bind(t : Task<'T>, f:'T -> Async<'R>) : Async<'R> = async.Bind (Async.AwaitTask t, f) |  | ||||||
| 
 |  | ||||||
|   /// An extension method that overloads the standard 'Bind' of the 'async' builder. The new overload awaits on |  | ||||||
|   /// a standard .NET task which does not commpute a value |  | ||||||
|   member x.Bind(t : Task, f : unit -> Async<'R>) : Async<'R> = async.Bind (Async.AwaitTask t, f) |  | ||||||
| 
 |  | ||||||
|   member x.ReturnFrom(t : Task<'T>) : Async<'T> = Async.AwaitTask t |  | ||||||
| @ -1,61 +0,0 @@ | |||||||
| namespace MyPrayerJournal.Migrations |  | ||||||
| 
 |  | ||||||
| open System |  | ||||||
| open Microsoft.EntityFrameworkCore |  | ||||||
| open Microsoft.EntityFrameworkCore.Infrastructure |  | ||||||
| open Microsoft.EntityFrameworkCore.Metadata |  | ||||||
| open Microsoft.EntityFrameworkCore.Migrations |  | ||||||
| open MyPrayerJournal |  | ||||||
| 
 |  | ||||||
| [<DbContext (typeof<DataContext>)>] |  | ||||||
| type DataContextModelSnapshot () = |  | ||||||
|   inherit ModelSnapshot () |  | ||||||
|   override this.BuildModel modelBuilder = |  | ||||||
|     modelBuilder |  | ||||||
|       .HasDefaultSchema("mpj") |  | ||||||
|       .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn) |  | ||||||
|       .HasAnnotation("ProductVersion", "1.1.0-rtm-22752") |  | ||||||
|     |> ignore |  | ||||||
| 
 |  | ||||||
|     modelBuilder.Entity("MyPrayerJournal.History", |  | ||||||
|       fun b -> |  | ||||||
|         b.Property<Guid>("RequestId") |  | ||||||
|         |> ignore |  | ||||||
|         b.Property<int64>("AsOf") |  | ||||||
|         |> ignore |  | ||||||
|         b.Property<string>("Status") |  | ||||||
|         |> ignore |  | ||||||
|         b.Property<string>("Text") |  | ||||||
|         |> ignore |  | ||||||
|         b.HasKey("RequestId", "AsOf") |  | ||||||
|         |> ignore |  | ||||||
|         b.ToTable("History") |  | ||||||
|         |> ignore |  | ||||||
|       ) |  | ||||||
|     |> ignore |  | ||||||
| 
 |  | ||||||
|     modelBuilder.Entity("MyPrayerJournal.Request", |  | ||||||
|       fun b -> |  | ||||||
|         b.Property<Guid>("RequestId") |  | ||||||
|           .ValueGeneratedOnAdd() |  | ||||||
|         |> ignore |  | ||||||
|         b.Property<int64>("EnteredOn") |  | ||||||
|         |> ignore |  | ||||||
|         b.Property<string>("UserId") |  | ||||||
|         |> ignore |  | ||||||
|         b.HasKey("RequestId") |  | ||||||
|         |> ignore |  | ||||||
|         b.ToTable("Request") |  | ||||||
|         |> ignore |  | ||||||
|       ) |  | ||||||
|     |> ignore |  | ||||||
| 
 |  | ||||||
|     modelBuilder.Entity("MyPrayerJournal.History", |  | ||||||
|       fun b -> |  | ||||||
|         b.HasOne("MyPrayerJournal.Request", "Request") |  | ||||||
|           .WithMany("History") |  | ||||||
|           .HasForeignKey("RequestId") |  | ||||||
|           .OnDelete(DeleteBehavior.Cascade) |  | ||||||
|         |> ignore |  | ||||||
|       ) |  | ||||||
|     |> ignore |  | ||||||
| @ -1,30 +0,0 @@ | |||||||
| <Project Sdk="Microsoft.NET.Sdk"> |  | ||||||
|   <PropertyGroup> |  | ||||||
|     <OutputType>Exe</OutputType> |  | ||||||
|     <TargetFramework>netcoreapp2.0</TargetFramework> |  | ||||||
|     <AssemblyName>myPrayerJournal</AssemblyName> |  | ||||||
|     <PackageId>MyPrayerJournal</PackageId> |  | ||||||
|     <VersionPrefix>0.8.1</VersionPrefix> |  | ||||||
|   </PropertyGroup> |  | ||||||
|   <ItemGroup> |  | ||||||
|     <Compile Include="Extensions.fs" /> |  | ||||||
|     <Compile Include="Entities.fs" /> |  | ||||||
|     <Compile Include="Dependencies.fs" /> |  | ||||||
|     <Compile Include="Data.fs" /> |  | ||||||
|     <Compile Include="Migrations/20170104023341_InitialDb.fs" /> |  | ||||||
|     <Compile Include="Migrations/DataContextModelSnapshot.fs" /> |  | ||||||
|     <Compile Include="App.fs" /> |  | ||||||
|     <None Include="appsettings.json" CopyToOutputDirectory="Always" /> |  | ||||||
|     <None Include="wwwroot/**" CopyToOutputDirectory="Always" /> |  | ||||||
|   </ItemGroup> |  | ||||||
|   <ItemGroup> |  | ||||||
|     <PackageReference Include="FSharp.Core" Version="4.2.3" /> |  | ||||||
|     <PackageReference Include="jose-jwt" Version="2.*" /> |  | ||||||
|     <PackageReference Include="Newtonsoft.Json" Version="10.*" /> |  | ||||||
|     <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="1.*" /> |  | ||||||
|     <PackageReference Include="Suave" Version="2.*" /> |  | ||||||
|   </ItemGroup> |  | ||||||
|   <ItemGroup> |  | ||||||
|     <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.*" /> |  | ||||||
|   </ItemGroup> |  | ||||||
| </Project> |  | ||||||
							
								
								
									
										18
									
								
								src/api/db/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/api/db/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | 'use strict' | ||||||
|  | 
 | ||||||
|  | const { Pool } = require('pg') | ||||||
|  | const config = require('../appsettings.json') | ||||||
|  | 
 | ||||||
|  | const pool = new Pool(config.pgPool) | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Run a SQL query | ||||||
|  |  * @param {string} text The SQL command | ||||||
|  |  * @param {*[]} params The parameters for the query | ||||||
|  |  */ | ||||||
|  | const query = (text, params) => pool.query(text, params) | ||||||
|  | 
 | ||||||
|  | module.exports = { | ||||||
|  |   query: query, | ||||||
|  |   request: require('./request')(query) | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								src/api/db/request.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/api/db/request.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | 'use strict' | ||||||
|  | 
 | ||||||
|  | const { Pool } = require('pg') | ||||||
|  | 
 | ||||||
|  | module.exports = query => { | ||||||
|  |   return { | ||||||
|  |     /** | ||||||
|  |      * Get the current requests for a user (i.e., their complete current journal) | ||||||
|  |      * @param {string} userId The Id of the user | ||||||
|  |      * @return The requests that make up the current journal | ||||||
|  |      */ | ||||||
|  |     journal: async userId => | ||||||
|  |       (await query('SELECT "RequestId" FROM "Request" WHERE "UserId" = $1', [userId])).rows | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										60
									
								
								src/api/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/api/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,60 @@ | |||||||
|  | 'use strict' | ||||||
|  | 
 | ||||||
|  | const express = require('express') | ||||||
|  | 
 | ||||||
|  | /** Configuration for the application */ | ||||||
|  | const config = require('./appsettings.json') | ||||||
|  | 
 | ||||||
|  | /** Express app */ | ||||||
|  | const app = express() | ||||||
|  | 
 | ||||||
|  | const jwt = require('express-jwt') | ||||||
|  | const jwksRsa = require('jwks-rsa') | ||||||
|  | 
 | ||||||
|  | // Authentication middleware. When used, the
 | ||||||
|  | // access token must exist and be verified against
 | ||||||
|  | // the Auth0 JSON Web Key Set
 | ||||||
|  | const checkJwt = jwt({ | ||||||
|  |   // Dynamically provide a signing key
 | ||||||
|  |   // based on the kid in the header and 
 | ||||||
|  |   // the singing keys provided by the JWKS endpoint.
 | ||||||
|  |   secret: jwksRsa.expressJwtSecret({ | ||||||
|  |     cache: true, | ||||||
|  |     rateLimit: true, | ||||||
|  |     jwksRequestsPerMinute: 5, | ||||||
|  |     jwksUri: `https://${config.auth0.domain}/.well-known/jwks.json` | ||||||
|  |   }), | ||||||
|  | 
 | ||||||
|  |   // Validate the audience and the issuer.
 | ||||||
|  |   audience: config.auth0.clientId, | ||||||
|  |   issuer: `https://${config.auth0.domain}/`, | ||||||
|  |   algorithms: ['RS256'] | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // Serve the Vue files from /public
 | ||||||
|  | app.use(express.static('public')) | ||||||
|  | 
 | ||||||
|  | // Logging FTW!
 | ||||||
|  | app.use(require('morgan')('dev')) | ||||||
|  | 
 | ||||||
|  | // Tie in all the API routes
 | ||||||
|  | require('./routes').mount(app, checkJwt) | ||||||
|  | 
 | ||||||
|  | // Send the index.html file for what would normally get a 404
 | ||||||
|  | app.use(async (req, res, next) => { | ||||||
|  |   const options = { | ||||||
|  |     root: __dirname + '/public/', | ||||||
|  |     dotfiles: 'deny' | ||||||
|  |   } | ||||||
|  |   try { | ||||||
|  |     await res.sendFile('index.html', options) | ||||||
|  |   } | ||||||
|  |   catch (err) { | ||||||
|  |     return next(err) | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | // Start it up!
 | ||||||
|  | app.listen(config.port, () => { | ||||||
|  |   console.log(`Listening on port ${config.port}`) | ||||||
|  | }) | ||||||
							
								
								
									
										21
									
								
								src/api/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/api/package.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | { | ||||||
|  |   "name": "my-prayer-journal-api", | ||||||
|  |   "private": true, | ||||||
|  |   "version": "0.8.0", | ||||||
|  |   "description": "Server API for myPrayerJournal", | ||||||
|  |   "main": "index.js", | ||||||
|  |   "author": "Daniel J. Summers <daniel@djs-consulting.com>", | ||||||
|  |   "license": "MIT", | ||||||
|  |   "dependencies": { | ||||||
|  |     "express": "^4.15.4", | ||||||
|  |     "express-jwt": "^5.3.0", | ||||||
|  |     "express-promise-router": "^2.0.0", | ||||||
|  |     "jwks-rsa": "^1.2.0", | ||||||
|  |     "morgan": "^1.8.2", | ||||||
|  |     "pg": "^7.3.0" | ||||||
|  |   }, | ||||||
|  |   "scripts": { | ||||||
|  |     "start": "node index.js", | ||||||
|  |     "vue": "cd ../app && node build/build.js prod && cd ../api && node index.js" | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										7
									
								
								src/api/routes/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/api/routes/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | |||||||
|  | 'use strict' | ||||||
|  | 
 | ||||||
|  | module.exports = { | ||||||
|  |   mount: (app, checkJwt) => { | ||||||
|  |     app.use('/api/journal', require('./journal')(checkJwt)) | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										15
									
								
								src/api/routes/journal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/api/routes/journal.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | |||||||
|  | 'use strict' | ||||||
|  | 
 | ||||||
|  | const Router = require('express-promise-router') | ||||||
|  | const db = require('../db') | ||||||
|  | 
 | ||||||
|  | module.exports = checkJwt => { | ||||||
|  |   let router = new Router() | ||||||
|  | 
 | ||||||
|  |   router.get('/', checkJwt, async (req, res) => { | ||||||
|  |     const reqs = await db.request.journal(req.user.sub) | ||||||
|  |     res.json(reqs) | ||||||
|  |   }) | ||||||
|  |   return router | ||||||
|  | } | ||||||
|  | 
 | ||||||
							
								
								
									
										826
									
								
								src/api/yarn.lock
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										826
									
								
								src/api/yarn.lock
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,826 @@ | |||||||
|  | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. | ||||||
|  | # yarn lockfile v1 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | "@types/express-jwt@0.0.34": | ||||||
|  |   version "0.0.34" | ||||||
|  |   resolved "https://registry.yarnpkg.com/@types/express-jwt/-/express-jwt-0.0.34.tgz#fdbee4c6af5c0a246ef2a933f5519973c7717f02" | ||||||
|  |   dependencies: | ||||||
|  |     "@types/express" "*" | ||||||
|  |     "@types/express-unless" "*" | ||||||
|  | 
 | ||||||
|  | "@types/express-serve-static-core@*": | ||||||
|  |   version "4.0.52" | ||||||
|  |   resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.0.52.tgz#77ab67fffc402ff6e480c87c71d799ba79880223" | ||||||
|  |   dependencies: | ||||||
|  |     "@types/node" "*" | ||||||
|  | 
 | ||||||
|  | "@types/express-unless@*": | ||||||
|  |   version "0.0.31" | ||||||
|  |   resolved "https://registry.yarnpkg.com/@types/express-unless/-/express-unless-0.0.31.tgz#cb6fa8a2e4d31a2ac4762d7aa00f5a258a701cb0" | ||||||
|  |   dependencies: | ||||||
|  |     "@types/express" "*" | ||||||
|  | 
 | ||||||
|  | "@types/express@*": | ||||||
|  |   version "4.0.37" | ||||||
|  |   resolved "https://registry.yarnpkg.com/@types/express/-/express-4.0.37.tgz#625ac3765169676e01897ca47011c26375784971" | ||||||
|  |   dependencies: | ||||||
|  |     "@types/express-serve-static-core" "*" | ||||||
|  |     "@types/serve-static" "*" | ||||||
|  | 
 | ||||||
|  | "@types/mime@*": | ||||||
|  |   version "1.3.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.1.tgz#2cf42972d0931c1060c7d5fa6627fce6bd876f2f" | ||||||
|  | 
 | ||||||
|  | "@types/node@*": | ||||||
|  |   version "8.0.28" | ||||||
|  |   resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.28.tgz#86206716f8d9251cf41692e384264cbd7058ad60" | ||||||
|  | 
 | ||||||
|  | "@types/serve-static@*": | ||||||
|  |   version "1.7.32" | ||||||
|  |   resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.7.32.tgz#0f6732e4dab0813771dd8fc8fe14940f34728b4c" | ||||||
|  |   dependencies: | ||||||
|  |     "@types/express-serve-static-core" "*" | ||||||
|  |     "@types/mime" "*" | ||||||
|  | 
 | ||||||
|  | accepts@~1.3.3: | ||||||
|  |   version "1.3.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.4.tgz#86246758c7dd6d21a6474ff084a4740ec05eb21f" | ||||||
|  |   dependencies: | ||||||
|  |     mime-types "~2.1.16" | ||||||
|  |     negotiator "0.6.1" | ||||||
|  | 
 | ||||||
|  | ajv@^4.9.1: | ||||||
|  |   version "4.11.8" | ||||||
|  |   resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" | ||||||
|  |   dependencies: | ||||||
|  |     co "^4.6.0" | ||||||
|  |     json-stable-stringify "^1.0.1" | ||||||
|  | 
 | ||||||
|  | array-flatten@1.1.1: | ||||||
|  |   version "1.1.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" | ||||||
|  | 
 | ||||||
|  | asn1@~0.2.3: | ||||||
|  |   version "0.2.3" | ||||||
|  |   resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" | ||||||
|  | 
 | ||||||
|  | assert-plus@1.0.0, assert-plus@^1.0.0: | ||||||
|  |   version "1.0.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" | ||||||
|  | 
 | ||||||
|  | assert-plus@^0.2.0: | ||||||
|  |   version "0.2.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" | ||||||
|  | 
 | ||||||
|  | async@^1.5.0: | ||||||
|  |   version "1.5.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" | ||||||
|  | 
 | ||||||
|  | asynckit@^0.4.0: | ||||||
|  |   version "0.4.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" | ||||||
|  | 
 | ||||||
|  | aws-sign2@~0.6.0: | ||||||
|  |   version "0.6.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" | ||||||
|  | 
 | ||||||
|  | aws4@^1.2.1: | ||||||
|  |   version "1.6.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" | ||||||
|  | 
 | ||||||
|  | base64url@2.0.0, base64url@^2.0.0: | ||||||
|  |   version "2.0.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/base64url/-/base64url-2.0.0.tgz#eac16e03ea1438eff9423d69baa36262ed1f70bb" | ||||||
|  | 
 | ||||||
|  | basic-auth@~1.1.0: | ||||||
|  |   version "1.1.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-1.1.0.tgz#45221ee429f7ee1e5035be3f51533f1cdfd29884" | ||||||
|  | 
 | ||||||
|  | bcrypt-pbkdf@^1.0.0: | ||||||
|  |   version "1.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" | ||||||
|  |   dependencies: | ||||||
|  |     tweetnacl "^0.14.3" | ||||||
|  | 
 | ||||||
|  | boom@2.x.x: | ||||||
|  |   version "2.10.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" | ||||||
|  |   dependencies: | ||||||
|  |     hoek "2.x.x" | ||||||
|  | 
 | ||||||
|  | buffer-equal-constant-time@1.0.1: | ||||||
|  |   version "1.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" | ||||||
|  | 
 | ||||||
|  | buffer-writer@1.0.1: | ||||||
|  |   version "1.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-1.0.1.tgz#22a936901e3029afcd7547eb4487ceb697a3bf08" | ||||||
|  | 
 | ||||||
|  | caseless@~0.12.0: | ||||||
|  |   version "0.12.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" | ||||||
|  | 
 | ||||||
|  | co@^4.6.0: | ||||||
|  |   version "4.6.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" | ||||||
|  | 
 | ||||||
|  | combined-stream@^1.0.5, combined-stream@~1.0.5: | ||||||
|  |   version "1.0.5" | ||||||
|  |   resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" | ||||||
|  |   dependencies: | ||||||
|  |     delayed-stream "~1.0.0" | ||||||
|  | 
 | ||||||
|  | content-disposition@0.5.2: | ||||||
|  |   version "0.5.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" | ||||||
|  | 
 | ||||||
|  | content-type@~1.0.2: | ||||||
|  |   version "1.0.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" | ||||||
|  | 
 | ||||||
|  | cookie-signature@1.0.6: | ||||||
|  |   version "1.0.6" | ||||||
|  |   resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" | ||||||
|  | 
 | ||||||
|  | cookie@0.3.1: | ||||||
|  |   version "0.3.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" | ||||||
|  | 
 | ||||||
|  | core-util-is@1.0.2: | ||||||
|  |   version "1.0.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" | ||||||
|  | 
 | ||||||
|  | cryptiles@2.x.x: | ||||||
|  |   version "2.0.5" | ||||||
|  |   resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" | ||||||
|  |   dependencies: | ||||||
|  |     boom "2.x.x" | ||||||
|  | 
 | ||||||
|  | dashdash@^1.12.0: | ||||||
|  |   version "1.14.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" | ||||||
|  |   dependencies: | ||||||
|  |     assert-plus "^1.0.0" | ||||||
|  | 
 | ||||||
|  | debug@2.6.8, debug@^2.2.0: | ||||||
|  |   version "2.6.8" | ||||||
|  |   resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" | ||||||
|  |   dependencies: | ||||||
|  |     ms "2.0.0" | ||||||
|  | 
 | ||||||
|  | delayed-stream@~1.0.0: | ||||||
|  |   version "1.0.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" | ||||||
|  | 
 | ||||||
|  | depd@1.1.1, depd@~1.1.0, depd@~1.1.1: | ||||||
|  |   version "1.1.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" | ||||||
|  | 
 | ||||||
|  | destroy@~1.0.4: | ||||||
|  |   version "1.0.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" | ||||||
|  | 
 | ||||||
|  | ecc-jsbn@~0.1.1: | ||||||
|  |   version "0.1.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" | ||||||
|  |   dependencies: | ||||||
|  |     jsbn "~0.1.0" | ||||||
|  | 
 | ||||||
|  | ecdsa-sig-formatter@1.0.9: | ||||||
|  |   version "1.0.9" | ||||||
|  |   resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz#4bc926274ec3b5abb5016e7e1d60921ac262b2a1" | ||||||
|  |   dependencies: | ||||||
|  |     base64url "^2.0.0" | ||||||
|  |     safe-buffer "^5.0.1" | ||||||
|  | 
 | ||||||
|  | ee-first@1.1.1: | ||||||
|  |   version "1.1.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" | ||||||
|  | 
 | ||||||
|  | encodeurl@~1.0.1: | ||||||
|  |   version "1.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" | ||||||
|  | 
 | ||||||
|  | escape-html@~1.0.3: | ||||||
|  |   version "1.0.3" | ||||||
|  |   resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" | ||||||
|  | 
 | ||||||
|  | etag@~1.8.0: | ||||||
|  |   version "1.8.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" | ||||||
|  | 
 | ||||||
|  | express-jwt@^5.3.0: | ||||||
|  |   version "5.3.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/express-jwt/-/express-jwt-5.3.0.tgz#3d90cd65802e6336252f19e6a3df3e149e0c5ea0" | ||||||
|  |   dependencies: | ||||||
|  |     async "^1.5.0" | ||||||
|  |     express-unless "^0.3.0" | ||||||
|  |     jsonwebtoken "^7.3.0" | ||||||
|  |     lodash.set "^4.0.0" | ||||||
|  | 
 | ||||||
|  | express-promise-router@^2.0.0: | ||||||
|  |   version "2.0.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/express-promise-router/-/express-promise-router-2.0.0.tgz#dd8c5894b40c061c8dcc6591d2145690e99e9551" | ||||||
|  |   dependencies: | ||||||
|  |     is-promise "^2.1.0" | ||||||
|  |     lodash "^4.13.1" | ||||||
|  |     methods "^1.0.0" | ||||||
|  | 
 | ||||||
|  | express-unless@^0.3.0: | ||||||
|  |   version "0.3.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/express-unless/-/express-unless-0.3.1.tgz#2557c146e75beb903e2d247f9b5ba01452696e20" | ||||||
|  | 
 | ||||||
|  | express@^4.15.4: | ||||||
|  |   version "4.15.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/express/-/express-4.15.4.tgz#032e2253489cf8fce02666beca3d11ed7a2daed1" | ||||||
|  |   dependencies: | ||||||
|  |     accepts "~1.3.3" | ||||||
|  |     array-flatten "1.1.1" | ||||||
|  |     content-disposition "0.5.2" | ||||||
|  |     content-type "~1.0.2" | ||||||
|  |     cookie "0.3.1" | ||||||
|  |     cookie-signature "1.0.6" | ||||||
|  |     debug "2.6.8" | ||||||
|  |     depd "~1.1.1" | ||||||
|  |     encodeurl "~1.0.1" | ||||||
|  |     escape-html "~1.0.3" | ||||||
|  |     etag "~1.8.0" | ||||||
|  |     finalhandler "~1.0.4" | ||||||
|  |     fresh "0.5.0" | ||||||
|  |     merge-descriptors "1.0.1" | ||||||
|  |     methods "~1.1.2" | ||||||
|  |     on-finished "~2.3.0" | ||||||
|  |     parseurl "~1.3.1" | ||||||
|  |     path-to-regexp "0.1.7" | ||||||
|  |     proxy-addr "~1.1.5" | ||||||
|  |     qs "6.5.0" | ||||||
|  |     range-parser "~1.2.0" | ||||||
|  |     send "0.15.4" | ||||||
|  |     serve-static "1.12.4" | ||||||
|  |     setprototypeof "1.0.3" | ||||||
|  |     statuses "~1.3.1" | ||||||
|  |     type-is "~1.6.15" | ||||||
|  |     utils-merge "1.0.0" | ||||||
|  |     vary "~1.1.1" | ||||||
|  | 
 | ||||||
|  | extend@~3.0.0: | ||||||
|  |   version "3.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" | ||||||
|  | 
 | ||||||
|  | extsprintf@1.3.0, extsprintf@^1.2.0: | ||||||
|  |   version "1.3.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" | ||||||
|  | 
 | ||||||
|  | finalhandler@~1.0.4: | ||||||
|  |   version "1.0.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.4.tgz#18574f2e7c4b98b8ae3b230c21f201f31bdb3fb7" | ||||||
|  |   dependencies: | ||||||
|  |     debug "2.6.8" | ||||||
|  |     encodeurl "~1.0.1" | ||||||
|  |     escape-html "~1.0.3" | ||||||
|  |     on-finished "~2.3.0" | ||||||
|  |     parseurl "~1.3.1" | ||||||
|  |     statuses "~1.3.1" | ||||||
|  |     unpipe "~1.0.0" | ||||||
|  | 
 | ||||||
|  | forever-agent@~0.6.1: | ||||||
|  |   version "0.6.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" | ||||||
|  | 
 | ||||||
|  | form-data@~2.1.1: | ||||||
|  |   version "2.1.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" | ||||||
|  |   dependencies: | ||||||
|  |     asynckit "^0.4.0" | ||||||
|  |     combined-stream "^1.0.5" | ||||||
|  |     mime-types "^2.1.12" | ||||||
|  | 
 | ||||||
|  | forwarded@~0.1.0: | ||||||
|  |   version "0.1.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" | ||||||
|  | 
 | ||||||
|  | fresh@0.5.0: | ||||||
|  |   version "0.5.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e" | ||||||
|  | 
 | ||||||
|  | getpass@^0.1.1: | ||||||
|  |   version "0.1.7" | ||||||
|  |   resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" | ||||||
|  |   dependencies: | ||||||
|  |     assert-plus "^1.0.0" | ||||||
|  | 
 | ||||||
|  | har-schema@^1.0.5: | ||||||
|  |   version "1.0.5" | ||||||
|  |   resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" | ||||||
|  | 
 | ||||||
|  | har-validator@~4.2.1: | ||||||
|  |   version "4.2.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" | ||||||
|  |   dependencies: | ||||||
|  |     ajv "^4.9.1" | ||||||
|  |     har-schema "^1.0.5" | ||||||
|  | 
 | ||||||
|  | hawk@~3.1.3: | ||||||
|  |   version "3.1.3" | ||||||
|  |   resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" | ||||||
|  |   dependencies: | ||||||
|  |     boom "2.x.x" | ||||||
|  |     cryptiles "2.x.x" | ||||||
|  |     hoek "2.x.x" | ||||||
|  |     sntp "1.x.x" | ||||||
|  | 
 | ||||||
|  | hoek@2.x.x: | ||||||
|  |   version "2.16.3" | ||||||
|  |   resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" | ||||||
|  | 
 | ||||||
|  | http-errors@~1.6.2: | ||||||
|  |   version "1.6.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" | ||||||
|  |   dependencies: | ||||||
|  |     depd "1.1.1" | ||||||
|  |     inherits "2.0.3" | ||||||
|  |     setprototypeof "1.0.3" | ||||||
|  |     statuses ">= 1.3.1 < 2" | ||||||
|  | 
 | ||||||
|  | http-signature@~1.1.0: | ||||||
|  |   version "1.1.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" | ||||||
|  |   dependencies: | ||||||
|  |     assert-plus "^0.2.0" | ||||||
|  |     jsprim "^1.2.2" | ||||||
|  |     sshpk "^1.7.0" | ||||||
|  | 
 | ||||||
|  | inherits@2.0.3: | ||||||
|  |   version "2.0.3" | ||||||
|  |   resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" | ||||||
|  | 
 | ||||||
|  | ipaddr.js@1.4.0: | ||||||
|  |   version "1.4.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.4.0.tgz#296aca878a821816e5b85d0a285a99bcff4582f0" | ||||||
|  | 
 | ||||||
|  | is-promise@^2.1.0: | ||||||
|  |   version "2.1.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" | ||||||
|  | 
 | ||||||
|  | is-typedarray@~1.0.0: | ||||||
|  |   version "1.0.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" | ||||||
|  | 
 | ||||||
|  | isemail@1.x.x: | ||||||
|  |   version "1.2.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/isemail/-/isemail-1.2.0.tgz#be03df8cc3e29de4d2c5df6501263f1fa4595e9a" | ||||||
|  | 
 | ||||||
|  | isstream@~0.1.2: | ||||||
|  |   version "0.1.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" | ||||||
|  | 
 | ||||||
|  | joi@^6.10.1: | ||||||
|  |   version "6.10.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/joi/-/joi-6.10.1.tgz#4d50c318079122000fe5f16af1ff8e1917b77e06" | ||||||
|  |   dependencies: | ||||||
|  |     hoek "2.x.x" | ||||||
|  |     isemail "1.x.x" | ||||||
|  |     moment "2.x.x" | ||||||
|  |     topo "1.x.x" | ||||||
|  | 
 | ||||||
|  | js-string-escape@1.0.1: | ||||||
|  |   version "1.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" | ||||||
|  | 
 | ||||||
|  | jsbn@~0.1.0: | ||||||
|  |   version "0.1.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" | ||||||
|  | 
 | ||||||
|  | json-schema@0.2.3: | ||||||
|  |   version "0.2.3" | ||||||
|  |   resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" | ||||||
|  | 
 | ||||||
|  | json-stable-stringify@^1.0.1: | ||||||
|  |   version "1.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" | ||||||
|  |   dependencies: | ||||||
|  |     jsonify "~0.0.0" | ||||||
|  | 
 | ||||||
|  | json-stringify-safe@~5.0.1: | ||||||
|  |   version "5.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" | ||||||
|  | 
 | ||||||
|  | jsonify@~0.0.0: | ||||||
|  |   version "0.0.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" | ||||||
|  | 
 | ||||||
|  | jsonwebtoken@^7.3.0: | ||||||
|  |   version "7.4.3" | ||||||
|  |   resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-7.4.3.tgz#77f5021de058b605a1783fa1283e99812e645638" | ||||||
|  |   dependencies: | ||||||
|  |     joi "^6.10.1" | ||||||
|  |     jws "^3.1.4" | ||||||
|  |     lodash.once "^4.0.0" | ||||||
|  |     ms "^2.0.0" | ||||||
|  |     xtend "^4.0.1" | ||||||
|  | 
 | ||||||
|  | jsprim@^1.2.2: | ||||||
|  |   version "1.4.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" | ||||||
|  |   dependencies: | ||||||
|  |     assert-plus "1.0.0" | ||||||
|  |     extsprintf "1.3.0" | ||||||
|  |     json-schema "0.2.3" | ||||||
|  |     verror "1.10.0" | ||||||
|  | 
 | ||||||
|  | jwa@^1.1.4: | ||||||
|  |   version "1.1.5" | ||||||
|  |   resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.5.tgz#a0552ce0220742cd52e153774a32905c30e756e5" | ||||||
|  |   dependencies: | ||||||
|  |     base64url "2.0.0" | ||||||
|  |     buffer-equal-constant-time "1.0.1" | ||||||
|  |     ecdsa-sig-formatter "1.0.9" | ||||||
|  |     safe-buffer "^5.0.1" | ||||||
|  | 
 | ||||||
|  | jwks-rsa@^1.2.0: | ||||||
|  |   version "1.2.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/jwks-rsa/-/jwks-rsa-1.2.0.tgz#b7e925b9eac0722ad8634ad6a7e97c7daed3d4c8" | ||||||
|  |   dependencies: | ||||||
|  |     "@types/express-jwt" "0.0.34" | ||||||
|  |     debug "^2.2.0" | ||||||
|  |     limiter "^1.1.0" | ||||||
|  |     lru-memoizer "^1.6.0" | ||||||
|  |     ms "^2.0.0" | ||||||
|  |     request "^2.73.0" | ||||||
|  | 
 | ||||||
|  | jws@^3.1.4: | ||||||
|  |   version "3.1.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.4.tgz#f9e8b9338e8a847277d6444b1464f61880e050a2" | ||||||
|  |   dependencies: | ||||||
|  |     base64url "^2.0.0" | ||||||
|  |     jwa "^1.1.4" | ||||||
|  |     safe-buffer "^5.0.1" | ||||||
|  | 
 | ||||||
|  | limiter@^1.1.0: | ||||||
|  |   version "1.1.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.2.tgz#229d8055891c8b11af9e0ee5200e8e09bb3dcbeb" | ||||||
|  | 
 | ||||||
|  | lock@~0.1.2: | ||||||
|  |   version "0.1.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/lock/-/lock-0.1.4.tgz#fec7deaef17e7c3a0a55e1da042803e25d91745d" | ||||||
|  | 
 | ||||||
|  | lodash.once@^4.0.0: | ||||||
|  |   version "4.1.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" | ||||||
|  | 
 | ||||||
|  | lodash.set@^4.0.0: | ||||||
|  |   version "4.3.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" | ||||||
|  | 
 | ||||||
|  | lodash@^4.13.1: | ||||||
|  |   version "4.17.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" | ||||||
|  | 
 | ||||||
|  | lodash@~4.5.1: | ||||||
|  |   version "4.5.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.5.1.tgz#80e8a074ca5f3893a6b1c10b2a636492d710c316" | ||||||
|  | 
 | ||||||
|  | lru-cache@~4.0.0: | ||||||
|  |   version "4.0.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" | ||||||
|  |   dependencies: | ||||||
|  |     pseudomap "^1.0.1" | ||||||
|  |     yallist "^2.0.0" | ||||||
|  | 
 | ||||||
|  | lru-memoizer@^1.6.0: | ||||||
|  |   version "1.11.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/lru-memoizer/-/lru-memoizer-1.11.1.tgz#0693f6100593914c02e192bf9b8d93884cbf50d3" | ||||||
|  |   dependencies: | ||||||
|  |     lock "~0.1.2" | ||||||
|  |     lodash "~4.5.1" | ||||||
|  |     lru-cache "~4.0.0" | ||||||
|  |     very-fast-args "^1.1.0" | ||||||
|  | 
 | ||||||
|  | media-typer@0.3.0: | ||||||
|  |   version "0.3.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" | ||||||
|  | 
 | ||||||
|  | merge-descriptors@1.0.1: | ||||||
|  |   version "1.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" | ||||||
|  | 
 | ||||||
|  | methods@^1.0.0, methods@~1.1.2: | ||||||
|  |   version "1.1.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" | ||||||
|  | 
 | ||||||
|  | mime-db@~1.30.0: | ||||||
|  |   version "1.30.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" | ||||||
|  | 
 | ||||||
|  | mime-types@^2.1.12, mime-types@~2.1.15, mime-types@~2.1.16, mime-types@~2.1.7: | ||||||
|  |   version "2.1.17" | ||||||
|  |   resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" | ||||||
|  |   dependencies: | ||||||
|  |     mime-db "~1.30.0" | ||||||
|  | 
 | ||||||
|  | mime@1.3.4: | ||||||
|  |   version "1.3.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" | ||||||
|  | 
 | ||||||
|  | moment@2.x.x: | ||||||
|  |   version "2.18.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" | ||||||
|  | 
 | ||||||
|  | morgan@^1.8.2: | ||||||
|  |   version "1.8.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.8.2.tgz#784ac7734e4a453a9c6e6e8680a9329275c8b687" | ||||||
|  |   dependencies: | ||||||
|  |     basic-auth "~1.1.0" | ||||||
|  |     debug "2.6.8" | ||||||
|  |     depd "~1.1.0" | ||||||
|  |     on-finished "~2.3.0" | ||||||
|  |     on-headers "~1.0.1" | ||||||
|  | 
 | ||||||
|  | ms@2.0.0, ms@^2.0.0: | ||||||
|  |   version "2.0.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" | ||||||
|  | 
 | ||||||
|  | negotiator@0.6.1: | ||||||
|  |   version "0.6.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" | ||||||
|  | 
 | ||||||
|  | oauth-sign@~0.8.1: | ||||||
|  |   version "0.8.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" | ||||||
|  | 
 | ||||||
|  | on-finished@~2.3.0: | ||||||
|  |   version "2.3.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" | ||||||
|  |   dependencies: | ||||||
|  |     ee-first "1.1.1" | ||||||
|  | 
 | ||||||
|  | on-headers@~1.0.1: | ||||||
|  |   version "1.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" | ||||||
|  | 
 | ||||||
|  | packet-reader@0.3.1: | ||||||
|  |   version "0.3.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-0.3.1.tgz#cd62e60af8d7fea8a705ec4ff990871c46871f27" | ||||||
|  | 
 | ||||||
|  | parseurl@~1.3.1: | ||||||
|  |   version "1.3.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" | ||||||
|  | 
 | ||||||
|  | path-to-regexp@0.1.7: | ||||||
|  |   version "0.1.7" | ||||||
|  |   resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" | ||||||
|  | 
 | ||||||
|  | performance-now@^0.2.0: | ||||||
|  |   version "0.2.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" | ||||||
|  | 
 | ||||||
|  | pg-connection-string@0.1.3: | ||||||
|  |   version "0.1.3" | ||||||
|  |   resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7" | ||||||
|  | 
 | ||||||
|  | pg-pool@~2.0.3: | ||||||
|  |   version "2.0.3" | ||||||
|  |   resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-2.0.3.tgz#c022032c8949f312a4f91fb6409ce04076be3257" | ||||||
|  | 
 | ||||||
|  | pg-types@~1.12.1: | ||||||
|  |   version "1.12.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-1.12.1.tgz#d64087e3903b58ffaad279e7595c52208a14c3d2" | ||||||
|  |   dependencies: | ||||||
|  |     postgres-array "~1.0.0" | ||||||
|  |     postgres-bytea "~1.0.0" | ||||||
|  |     postgres-date "~1.0.0" | ||||||
|  |     postgres-interval "^1.1.0" | ||||||
|  | 
 | ||||||
|  | pg@^7.3.0: | ||||||
|  |   version "7.3.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/pg/-/pg-7.3.0.tgz#275e27466e54a645f6b4a16f6acadf6b849ad83b" | ||||||
|  |   dependencies: | ||||||
|  |     buffer-writer "1.0.1" | ||||||
|  |     js-string-escape "1.0.1" | ||||||
|  |     packet-reader "0.3.1" | ||||||
|  |     pg-connection-string "0.1.3" | ||||||
|  |     pg-pool "~2.0.3" | ||||||
|  |     pg-types "~1.12.1" | ||||||
|  |     pgpass "1.x" | ||||||
|  |     semver "4.3.2" | ||||||
|  | 
 | ||||||
|  | pgpass@1.x: | ||||||
|  |   version "1.0.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.2.tgz#2a7bb41b6065b67907e91da1b07c1847c877b306" | ||||||
|  |   dependencies: | ||||||
|  |     split "^1.0.0" | ||||||
|  | 
 | ||||||
|  | postgres-array@~1.0.0: | ||||||
|  |   version "1.0.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-1.0.2.tgz#8e0b32eb03bf77a5c0a7851e0441c169a256a238" | ||||||
|  | 
 | ||||||
|  | postgres-bytea@~1.0.0: | ||||||
|  |   version "1.0.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" | ||||||
|  | 
 | ||||||
|  | postgres-date@~1.0.0: | ||||||
|  |   version "1.0.3" | ||||||
|  |   resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.3.tgz#e2d89702efdb258ff9d9cee0fe91bd06975257a8" | ||||||
|  | 
 | ||||||
|  | postgres-interval@^1.1.0: | ||||||
|  |   version "1.1.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.1.1.tgz#acdb0f897b4b1c6e496d9d4e0a853e1c428f06f0" | ||||||
|  |   dependencies: | ||||||
|  |     xtend "^4.0.0" | ||||||
|  | 
 | ||||||
|  | proxy-addr@~1.1.5: | ||||||
|  |   version "1.1.5" | ||||||
|  |   resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.5.tgz#71c0ee3b102de3f202f3b64f608d173fcba1a918" | ||||||
|  |   dependencies: | ||||||
|  |     forwarded "~0.1.0" | ||||||
|  |     ipaddr.js "1.4.0" | ||||||
|  | 
 | ||||||
|  | pseudomap@^1.0.1: | ||||||
|  |   version "1.0.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" | ||||||
|  | 
 | ||||||
|  | punycode@^1.4.1: | ||||||
|  |   version "1.4.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" | ||||||
|  | 
 | ||||||
|  | qs@6.5.0: | ||||||
|  |   version "6.5.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.0.tgz#8d04954d364def3efc55b5a0793e1e2c8b1e6e49" | ||||||
|  | 
 | ||||||
|  | qs@~6.4.0: | ||||||
|  |   version "6.4.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" | ||||||
|  | 
 | ||||||
|  | range-parser@~1.2.0: | ||||||
|  |   version "1.2.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" | ||||||
|  | 
 | ||||||
|  | request@^2.73.0: | ||||||
|  |   version "2.81.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" | ||||||
|  |   dependencies: | ||||||
|  |     aws-sign2 "~0.6.0" | ||||||
|  |     aws4 "^1.2.1" | ||||||
|  |     caseless "~0.12.0" | ||||||
|  |     combined-stream "~1.0.5" | ||||||
|  |     extend "~3.0.0" | ||||||
|  |     forever-agent "~0.6.1" | ||||||
|  |     form-data "~2.1.1" | ||||||
|  |     har-validator "~4.2.1" | ||||||
|  |     hawk "~3.1.3" | ||||||
|  |     http-signature "~1.1.0" | ||||||
|  |     is-typedarray "~1.0.0" | ||||||
|  |     isstream "~0.1.2" | ||||||
|  |     json-stringify-safe "~5.0.1" | ||||||
|  |     mime-types "~2.1.7" | ||||||
|  |     oauth-sign "~0.8.1" | ||||||
|  |     performance-now "^0.2.0" | ||||||
|  |     qs "~6.4.0" | ||||||
|  |     safe-buffer "^5.0.1" | ||||||
|  |     stringstream "~0.0.4" | ||||||
|  |     tough-cookie "~2.3.0" | ||||||
|  |     tunnel-agent "^0.6.0" | ||||||
|  |     uuid "^3.0.0" | ||||||
|  | 
 | ||||||
|  | safe-buffer@^5.0.1: | ||||||
|  |   version "5.1.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" | ||||||
|  | 
 | ||||||
|  | semver@4.3.2: | ||||||
|  |   version "4.3.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7" | ||||||
|  | 
 | ||||||
|  | send@0.15.4: | ||||||
|  |   version "0.15.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/send/-/send-0.15.4.tgz#985faa3e284b0273c793364a35c6737bd93905b9" | ||||||
|  |   dependencies: | ||||||
|  |     debug "2.6.8" | ||||||
|  |     depd "~1.1.1" | ||||||
|  |     destroy "~1.0.4" | ||||||
|  |     encodeurl "~1.0.1" | ||||||
|  |     escape-html "~1.0.3" | ||||||
|  |     etag "~1.8.0" | ||||||
|  |     fresh "0.5.0" | ||||||
|  |     http-errors "~1.6.2" | ||||||
|  |     mime "1.3.4" | ||||||
|  |     ms "2.0.0" | ||||||
|  |     on-finished "~2.3.0" | ||||||
|  |     range-parser "~1.2.0" | ||||||
|  |     statuses "~1.3.1" | ||||||
|  | 
 | ||||||
|  | serve-static@1.12.4: | ||||||
|  |   version "1.12.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.4.tgz#9b6aa98eeb7253c4eedc4c1f6fdbca609901a961" | ||||||
|  |   dependencies: | ||||||
|  |     encodeurl "~1.0.1" | ||||||
|  |     escape-html "~1.0.3" | ||||||
|  |     parseurl "~1.3.1" | ||||||
|  |     send "0.15.4" | ||||||
|  | 
 | ||||||
|  | setprototypeof@1.0.3: | ||||||
|  |   version "1.0.3" | ||||||
|  |   resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" | ||||||
|  | 
 | ||||||
|  | sntp@1.x.x: | ||||||
|  |   version "1.0.9" | ||||||
|  |   resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" | ||||||
|  |   dependencies: | ||||||
|  |     hoek "2.x.x" | ||||||
|  | 
 | ||||||
|  | split@^1.0.0: | ||||||
|  |   version "1.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" | ||||||
|  |   dependencies: | ||||||
|  |     through "2" | ||||||
|  | 
 | ||||||
|  | sshpk@^1.7.0: | ||||||
|  |   version "1.13.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3" | ||||||
|  |   dependencies: | ||||||
|  |     asn1 "~0.2.3" | ||||||
|  |     assert-plus "^1.0.0" | ||||||
|  |     dashdash "^1.12.0" | ||||||
|  |     getpass "^0.1.1" | ||||||
|  |   optionalDependencies: | ||||||
|  |     bcrypt-pbkdf "^1.0.0" | ||||||
|  |     ecc-jsbn "~0.1.1" | ||||||
|  |     jsbn "~0.1.0" | ||||||
|  |     tweetnacl "~0.14.0" | ||||||
|  | 
 | ||||||
|  | "statuses@>= 1.3.1 < 2", statuses@~1.3.1: | ||||||
|  |   version "1.3.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" | ||||||
|  | 
 | ||||||
|  | stringstream@~0.0.4: | ||||||
|  |   version "0.0.5" | ||||||
|  |   resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" | ||||||
|  | 
 | ||||||
|  | through@2: | ||||||
|  |   version "2.3.8" | ||||||
|  |   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" | ||||||
|  | 
 | ||||||
|  | topo@1.x.x: | ||||||
|  |   version "1.1.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/topo/-/topo-1.1.0.tgz#e9d751615d1bb87dc865db182fa1ca0a5ef536d5" | ||||||
|  |   dependencies: | ||||||
|  |     hoek "2.x.x" | ||||||
|  | 
 | ||||||
|  | tough-cookie@~2.3.0: | ||||||
|  |   version "2.3.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" | ||||||
|  |   dependencies: | ||||||
|  |     punycode "^1.4.1" | ||||||
|  | 
 | ||||||
|  | tunnel-agent@^0.6.0: | ||||||
|  |   version "0.6.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" | ||||||
|  |   dependencies: | ||||||
|  |     safe-buffer "^5.0.1" | ||||||
|  | 
 | ||||||
|  | tweetnacl@^0.14.3, tweetnacl@~0.14.0: | ||||||
|  |   version "0.14.5" | ||||||
|  |   resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" | ||||||
|  | 
 | ||||||
|  | type-is@~1.6.15: | ||||||
|  |   version "1.6.15" | ||||||
|  |   resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.15.tgz#cab10fb4909e441c82842eafe1ad646c81804410" | ||||||
|  |   dependencies: | ||||||
|  |     media-typer "0.3.0" | ||||||
|  |     mime-types "~2.1.15" | ||||||
|  | 
 | ||||||
|  | unpipe@~1.0.0: | ||||||
|  |   version "1.0.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" | ||||||
|  | 
 | ||||||
|  | utils-merge@1.0.0: | ||||||
|  |   version "1.0.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" | ||||||
|  | 
 | ||||||
|  | uuid@^3.0.0: | ||||||
|  |   version "3.1.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04" | ||||||
|  | 
 | ||||||
|  | vary@~1.1.1: | ||||||
|  |   version "1.1.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37" | ||||||
|  | 
 | ||||||
|  | verror@1.10.0: | ||||||
|  |   version "1.10.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" | ||||||
|  |   dependencies: | ||||||
|  |     assert-plus "^1.0.0" | ||||||
|  |     core-util-is "1.0.2" | ||||||
|  |     extsprintf "^1.2.0" | ||||||
|  | 
 | ||||||
|  | very-fast-args@^1.1.0: | ||||||
|  |   version "1.1.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/very-fast-args/-/very-fast-args-1.1.0.tgz#e16d1d1faf8a6e596a246421fd90a77963d0b396" | ||||||
|  | 
 | ||||||
|  | xtend@^4.0.0, xtend@^4.0.1: | ||||||
|  |   version "4.0.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" | ||||||
|  | 
 | ||||||
|  | yallist@^2.0.0: | ||||||
|  |   version "2.1.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" | ||||||
| @ -4,8 +4,8 @@ var path = require('path') | |||||||
| module.exports = { | module.exports = { | ||||||
|   build: { |   build: { | ||||||
|     env: require('./prod.env'), |     env: require('./prod.env'), | ||||||
|     index: path.resolve(__dirname, '../../api/wwwroot/index.html'), |     index: path.resolve(__dirname, '../../api/public/index.html'), | ||||||
|     assetsRoot: path.resolve(__dirname, '../../api/wwwroot'), |     assetsRoot: path.resolve(__dirname, '../../api/public'), | ||||||
|     assetsSubDirectory: 'static', |     assetsSubDirectory: 'static', | ||||||
|     assetsPublicPath: '/', |     assetsPublicPath: '/', | ||||||
|     productionSourceMap: true, |     productionSourceMap: true, | ||||||
|  | |||||||
| @ -1,7 +1,7 @@ | |||||||
| import axios from 'axios' | import axios from 'axios' | ||||||
| 
 | 
 | ||||||
| const http = axios.create({ | const http = axios.create({ | ||||||
|   baseURL: 'http://localhost:8084/api' |   baseURL: 'http://localhost:3000/api/' | ||||||
| }) | }) | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
| @ -13,16 +13,16 @@ export default { | |||||||
|    * Set the bearer token for all future requests |    * Set the bearer token for all future requests | ||||||
|    * @param {string} token The token to use to identify the user to the server |    * @param {string} token The token to use to identify the user to the server | ||||||
|    */ |    */ | ||||||
|   setBearer: token => { http.defaults.headers.common['Authentication'] = `Bearer ${token}` }, |   setBearer: token => { http.defaults.headers.common['authorization'] = `Bearer ${token}` }, | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|    * Remove the bearer token |    * Remove the bearer token | ||||||
|    */ |    */ | ||||||
|   removeBearer: () => delete http.defaults.headers.common['Authentication'], |   removeBearer: () => delete http.defaults.headers.common['authorization'], | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|    * Get all prayer requests and their most recent updates |    * Get all prayer requests and their most recent updates | ||||||
|    */ |    */ | ||||||
|   journal: () => http.get('/journal') |   journal: () => http.get('journal/') | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -41,10 +41,12 @@ export default new Vuex.Store({ | |||||||
|     [types.USER_LOGGED_ON] (state, user) { |     [types.USER_LOGGED_ON] (state, user) { | ||||||
|       localStorage.setItem('user_profile', JSON.stringify(user)) |       localStorage.setItem('user_profile', JSON.stringify(user)) | ||||||
|       state.user = user |       state.user = user | ||||||
|  |       api.setBearer(localStorage.getItem('id_token')) | ||||||
|       state.isAuthenticated = true |       state.isAuthenticated = true | ||||||
|     }, |     }, | ||||||
|     [types.USER_LOGGED_OFF] (state) { |     [types.USER_LOGGED_OFF] (state) { | ||||||
|       state.user = {} |       state.user = {} | ||||||
|  |       api.removeBearer() | ||||||
|       state.isAuthenticated = false |       state.isAuthenticated = false | ||||||
|     }, |     }, | ||||||
|     [types.LOADING_JOURNAL] (state, flag) { |     [types.LOADING_JOURNAL] (state, flag) { | ||||||
| @ -58,10 +60,11 @@ export default new Vuex.Store({ | |||||||
|     [actions.LOAD_JOURNAL] ({ commit }) { |     [actions.LOAD_JOURNAL] ({ commit }) { | ||||||
|       commit(types.LOADED_JOURNAL, {}) |       commit(types.LOADED_JOURNAL, {}) | ||||||
|       commit(types.LOADING_JOURNAL, true) |       commit(types.LOADING_JOURNAL, true) | ||||||
|  |       api.setBearer(localStorage.getItem('id_token')) | ||||||
|       api.journal() |       api.journal() | ||||||
|         .then(jrnl => { |         .then(jrnl => { | ||||||
|           commit(types.LOADING_JOURNAL, false) |           commit(types.LOADING_JOURNAL, false) | ||||||
|           commit(types.LOADED_JOURNAL, jrnl) |           commit(types.LOADED_JOURNAL, jrnl.data) | ||||||
|         }) |         }) | ||||||
|         .catch(err => { |         .catch(err => { | ||||||
|           commit(types.LOADING_JOURNAL, false) |           commit(types.LOADING_JOURNAL, false) | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user