mirror of
https://github.com/status-im/fathom.git
synced 2025-03-01 03:20:27 +00:00
assume dashboard is public when there are no users in connected datastore. #117
This commit is contained in:
parent
291d53fcaf
commit
221e6394de
@ -16,6 +16,10 @@ class LogoutButton extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
if(document.cookie.indexOf('auth') < 0) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a href="#" onClick={this.handleSubmit}>Sign out</a>
|
<a href="#" onClick={this.handleSubmit}>Sign out</a>
|
||||||
)
|
)
|
||||||
|
@ -17,6 +17,7 @@ class Dashboard extends Component {
|
|||||||
period: (window.location.hash.substring(2) || 'last-7-days'),
|
period: (window.location.hash.substring(2) || 'last-7-days'),
|
||||||
before: 0,
|
before: 0,
|
||||||
after: 0,
|
after: 0,
|
||||||
|
isPublic: document.cookie.indexOf('auth') < 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -27,6 +28,11 @@ class Dashboard extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render(props, state) {
|
render(props, state) {
|
||||||
|
// only show logout link if this dashboard is not public
|
||||||
|
let logoutMenuItem = state.isPublic ? '' : (
|
||||||
|
<li class="signout"><span class="spacer">·</span><LogoutButton onSuccess={props.onLogout} /></li>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="app-page wrapper">
|
<div class="app-page wrapper">
|
||||||
|
|
||||||
@ -34,9 +40,8 @@ class Dashboard extends Component {
|
|||||||
<nav class="main-nav animated fadeInDown">
|
<nav class="main-nav animated fadeInDown">
|
||||||
<ul>
|
<ul>
|
||||||
<li class="logo"><a href="/">Fathom</a></li>
|
<li class="logo"><a href="/">Fathom</a></li>
|
||||||
<li class="visitors"><Realtime onError={props.onLogout} /></li>
|
<li class="visitors"><Realtime /></li>
|
||||||
<li class="spacer">·</li>
|
{logoutMenuItem}
|
||||||
<li class="signout"><LogoutButton onSuccess={props.onLogout} /></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
@ -4,6 +4,7 @@ import { h, render, Component } from 'preact'
|
|||||||
import Login from './pages/login.js'
|
import Login from './pages/login.js'
|
||||||
import Dashboard from './pages/dashboard.js'
|
import Dashboard from './pages/dashboard.js'
|
||||||
import { bind } from 'decko';
|
import { bind } from 'decko';
|
||||||
|
import Client from './lib/client.js';
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -12,6 +13,16 @@ class App extends Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
authenticated: document.cookie.indexOf('auth') > -1
|
authenticated: document.cookie.indexOf('auth') > -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.fetchAuthStatus()
|
||||||
|
}
|
||||||
|
|
||||||
|
@bind
|
||||||
|
fetchAuthStatus() {
|
||||||
|
Client.request(`session`)
|
||||||
|
.then((d) => {
|
||||||
|
this.setState({ authenticated: d })
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@bind
|
@bind
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
@ -25,8 +24,30 @@ func (l *login) Sanitize() {
|
|||||||
l.Email = strings.ToLower(strings.TrimSpace(l.Email))
|
l.Email = strings.ToLower(strings.TrimSpace(l.Email))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET /api/session
|
||||||
|
func (api *API) GetSession(w http.ResponseWriter, r *http.Request) error {
|
||||||
|
userCount, err := api.database.CountUsers()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// if 0 users in database, dashboard is public
|
||||||
|
if userCount == 0 {
|
||||||
|
return respond(w, envelope{Data: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
// if existing session, assume logged-in
|
||||||
|
session, _ := api.sessions.Get(r, "auth")
|
||||||
|
if !session.IsNew {
|
||||||
|
respond(w, envelope{Data: true})
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise: not logged-in yet
|
||||||
|
return respond(w, envelope{Data: false})
|
||||||
|
}
|
||||||
|
|
||||||
// URL: POST /api/session
|
// URL: POST /api/session
|
||||||
func (api *API) LoginHandler(w http.ResponseWriter, r *http.Request) error {
|
func (api *API) CreateSession(w http.ResponseWriter, r *http.Request) error {
|
||||||
// check login creds
|
// check login creds
|
||||||
var l login
|
var l login
|
||||||
err := json.NewDecoder(r.Body).Decode(&l)
|
err := json.NewDecoder(r.Body).Decode(&l)
|
||||||
@ -59,7 +80,7 @@ func (api *API) LoginHandler(w http.ResponseWriter, r *http.Request) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// URL: DELETE /api/session
|
// URL: DELETE /api/session
|
||||||
func (api *API) LogoutHandler(w http.ResponseWriter, r *http.Request) error {
|
func (api *API) DeleteSession(w http.ResponseWriter, r *http.Request) error {
|
||||||
session, _ := api.sessions.Get(r, "auth")
|
session, _ := api.sessions.Get(r, "auth")
|
||||||
if !session.IsNew {
|
if !session.IsNew {
|
||||||
session.Options.MaxAge = -1
|
session.Options.MaxAge = -1
|
||||||
@ -79,27 +100,35 @@ func (api *API) Authorize(next http.Handler) http.Handler {
|
|||||||
// see http://www.gorillatoolkit.org/pkg/sessions#overview
|
// see http://www.gorillatoolkit.org/pkg/sessions#overview
|
||||||
defer gcontext.Clear(r)
|
defer gcontext.Clear(r)
|
||||||
|
|
||||||
session, err := api.sessions.Get(r, "auth")
|
// first count users in datastore
|
||||||
// an err is returned if cookie has been tampered with, so check that
|
// if 0, assume dashboard is public
|
||||||
|
userCount, err := api.database.CountUsers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userID, ok := session.Values["user_id"]
|
if userCount > 0 {
|
||||||
if session.IsNew || !ok {
|
session, err := api.sessions.Get(r, "auth")
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
// an err is returned if cookie has been tampered with, so check that
|
||||||
return
|
if err != nil {
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
userID, ok := session.Values["user_id"]
|
||||||
|
if session.IsNew || !ok {
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate user ID in session
|
||||||
|
if _, err := api.database.GetUser(userID.(int64)); err != nil {
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// find user
|
next.ServeHTTP(w, r)
|
||||||
u, err := api.database.GetUser(userID.(int64))
|
|
||||||
if err != nil {
|
|
||||||
w.WriteHeader(http.StatusUnauthorized)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := context.WithValue(r.Context(), userKey, u)
|
|
||||||
next.ServeHTTP(w, r.WithContext(ctx))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,10 @@ func (api *API) Routes() *mux.Router {
|
|||||||
// register routes
|
// register routes
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
r.Handle("/collect", NewCollector(api.database)).Methods(http.MethodGet)
|
r.Handle("/collect", NewCollector(api.database)).Methods(http.MethodGet)
|
||||||
r.Handle("/api/session", HandlerFunc(api.LoginHandler)).Methods(http.MethodPost)
|
|
||||||
r.Handle("/api/session", HandlerFunc(api.LogoutHandler)).Methods(http.MethodDelete)
|
r.Handle("/api/session", HandlerFunc(api.GetSession)).Methods(http.MethodGet)
|
||||||
|
r.Handle("/api/session", HandlerFunc(api.CreateSession)).Methods(http.MethodPost)
|
||||||
|
r.Handle("/api/session", HandlerFunc(api.DeleteSession)).Methods(http.MethodDelete)
|
||||||
|
|
||||||
r.Handle("/api/stats/site", api.Authorize(HandlerFunc(api.GetSiteStatsHandler))).Methods(http.MethodGet)
|
r.Handle("/api/stats/site", api.Authorize(HandlerFunc(api.GetSiteStatsHandler))).Methods(http.MethodGet)
|
||||||
r.Handle("/api/stats/site/groupby/day", api.Authorize(HandlerFunc(api.GetSiteStatsPerDayHandler))).Methods(http.MethodGet)
|
r.Handle("/api/stats/site/groupby/day", api.Authorize(HandlerFunc(api.GetSiteStatsPerDayHandler))).Methods(http.MethodGet)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user