summaryrefslogtreecommitdiff
path: root/fig-web/src/Fig/Web/Public.hs
blob: 1ff9962ba51d1acf852b56a2774cb791ea258ba1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
module Fig.Web.Public
  ( server
  ) where

import Fig.Prelude

import qualified Network.Wai as Wai
import qualified Network.Wai.Middleware.Static as Wai.Static
import qualified Network.Wai.Handler.Warp as Warp

import qualified Web.Scotty as Sc

import Fig.Bus.Binary.Client
import Fig.Web.Types
import Fig.Web.Utils
import qualified Fig.Web.DB as DB
import qualified Fig.Web.Module.Misc as Misc
import qualified Fig.Web.Module.TwitchAuth as TwitchAuth
import qualified Fig.Web.Module.Exchange as Exchange
import qualified Fig.Web.Module.Gizmo as Gizmo
import qualified Fig.Web.Module.Sentiment as Sentiment
import qualified Fig.Web.Module.Circle as Circle
import qualified Fig.Web.Module.Model as Model
import qualified Fig.Web.Module.Bells as Bells
import qualified Fig.Web.Module.User as User
import qualified Fig.Web.Module.Shader as Shader

allBusEvents :: PublicModuleArgs -> BusEventHandlers
allBusEvents args = busEvents . mconcat $ fmap ($ args)
  [ Gizmo.publicBusEvents
  , Circle.publicBusEvents
  ]

server :: PublicOptions -> Config -> (Text, Text) -> IO ()
server options cfg busAddr = do
  log $ "Web server running on port " <> tshow cfg.port
  log "Connecting to database..."
  db <- DB.connect cfg
  channels <- newChannels
  globals <- newGlobals
  busClient busAddr
    (\cmds -> do
        log "Connected to bus!"
        let args = ModuleArgs{..}
        subscribeBusEvents cmds $ allBusEvents args
        Warp.run cfg.port =<< app args
    )
    (\cmds ev d -> do
        let args = ModuleArgs{..}
        handleBusEvent (allBusEvents args) ev d
    )
    (pure ())

app :: PublicModuleArgs -> IO Wai.Application
app args = do
  log "Connected! Server active."
  Sc.scottyApp do
    Sc.middleware . Wai.Static.staticPolicy $ mconcat
      [ Wai.Static.isNotAbsolute
      , Wai.Static.only
        [ ("register", "register.html")
        , ("gizmo", "gizmo.html")
        , ("main.css", "main.css")
        , ("main.js", "main.js")
        ] Wai.Static.<|> Wai.Static.hasPrefix "assets"
      , Wai.Static.addBase args.cfg.assetPath
      ]
    onGet "/unauthorized" do
      status status401
      respondText $ mconcat
        [ "your request was rejected because that endpoint requires authentication\n"
        , "you can log in by POSTing your credentials to https://auth.colonq.computer/api/firstfactor\n"
        , "for example:\n"
        , "  curl https://auth.colonq.computer/api/firstfactor \\\n"
        , "    --header \"Content-Type: application/json\" \\\n"
        , "    --request POST \\\n"
        , "    --data '{\"username\":\"AzureDiamond\",\"password\":\"hunter2\"}' \\\n"
        , "    --cookie-jar cookies.txt\n"
        , "this will write a cookie called \"authelia_session\" to cookies.txt\n"
        , "send this cookie along with your requests to use the secure endpoints\n"
        , "for example:\n"
        , "  curl https://secure.colonq.computer --cookie cookies.txt\n"
        ]
    Misc.public args
    TwitchAuth.public args
    Exchange.public args
    Gizmo.public args
    Sentiment.public args
    Circle.public args
    Bells.public args
    User.public args
    Shader.public args
    websocket $ mconcat
      [ Gizmo.publicWebsockets args
      , Circle.publicWebsockets args
      , Model.publicWebsockets args
      ]
    Sc.notFound do
      respondText "not found"