Skip to content

Commit 17c535e

Browse files
welcome (#72)
* welcome * Update screenshots * fix demo user * Update screenshots --------- Co-authored-by: dylan-botler[bot] <dylan-botler[bot]@users.noreply.github.com>
1 parent cc82310 commit 17c535e

10 files changed

Lines changed: 1405 additions & 8 deletions

File tree

docs/screenshots/.content-hash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
31fad4a29cc5f862542a4f998913c7cb5ebf78d281fd1d57fb8878760c7a74bb
1+
856dfd1ef54fae7d3742610df73623bb72be071168a9a19f921bf90817a6f450

docs/screenshots/home.png

-106 Bytes
Loading

go/cmd/float/main.go

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"database/sql"
66
"log"
77
"os"
8+
"strings"
89

910
firebase "firebase.google.com/go/v4"
1011
"firebase.google.com/go/v4/messaging"
@@ -73,12 +74,31 @@ func setup(r *gin.Engine) (*api.API, gin.HandlerFunc) {
7374
if err != nil {
7475
log.Fatalf("failed to seed demo data: %v", err)
7576
}
77+
if err := queries.SetUserToken(context.Background(), userID, sql.NullString{String: "demo:token", Valid: true}); err != nil {
78+
log.Fatalf("failed to set demo user token: %v", err)
79+
}
7680
return api.New(queries, fx, classifier, push), middleware.DemoAuth(userID)
7781
}
7882

7983
webhook.New(queries, classifier, push).Register(r.Group("/webhook"))
8084

81-
return api.New(queries, fx, classifier, push), middleware.Middleware(queries, os.Getenv("BASE_URL"))
85+
teamDomain := os.Getenv("CF_ACCESS_TEAM_DOMAIN")
86+
audRaw := os.Getenv("CF_ACCESS_AUD")
87+
if teamDomain == "" || audRaw == "" {
88+
log.Fatalf("CF_ACCESS_TEAM_DOMAIN and CF_ACCESS_AUD must be set")
89+
}
90+
var audiences []string
91+
for _, a := range strings.Split(audRaw, ",") {
92+
if a = strings.TrimSpace(a); a != "" {
93+
audiences = append(audiences, a)
94+
}
95+
}
96+
verifier, err := middleware.NewCloudflareAccessVerifier(teamDomain, audiences)
97+
if err != nil {
98+
log.Fatalf("failed to init cf access verifier: %v", err)
99+
}
100+
101+
return api.New(queries, fx, classifier, push), middleware.Middleware(queries, os.Getenv("BASE_URL"), verifier)
82102
}
83103

84104
func newFCMClient() *messaging.Client {

go/middleware/middleware.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,23 @@ import (
1414
"dbut.dev/float/go/service"
1515
)
1616

17-
func Middleware(queries database.Querier, baseURL string) gin.HandlerFunc {
17+
func Middleware(queries database.Querier, baseURL string, verifier *CloudflareAccessVerifier) gin.HandlerFunc {
1818
webhookSvc := service.NewWebhookService(queries, nil, nil)
1919

2020
var emailToUserID sync.Map
2121
var generalBucketEnsured sync.Map
2222
var webhookConfirmed sync.Map
2323

2424
return func(c *gin.Context) {
25-
email := c.GetHeader("Cf-Access-Authenticated-User-Email")
25+
token := c.GetHeader("Cf-Access-Jwt-Assertion")
26+
if token == "" {
27+
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
28+
return
29+
}
2630

27-
if email == "" {
31+
email, err := verifier.Verify(token)
32+
if err != nil {
33+
log.Printf("cf access: jwt verification failed: %v", err)
2834
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
2935
return
3036
}

go/service/user.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type User struct {
1818
UserID uuid.UUID `json:"user_id"`
1919
Email string `json:"email"`
2020
CreatedAt time.Time `json:"created_at"`
21+
HasToken bool `json:"has_token"`
2122
}
2223

2324
type UserService struct {
@@ -37,7 +38,12 @@ func (s *UserService) GetUser(ctx context.Context, userID uuid.UUID) (User, erro
3738
if err != nil {
3839
return User{}, err
3940
}
40-
return User{UserID: u.UserID, Email: u.Email, CreatedAt: u.CreatedAt}, nil
41+
return User{
42+
UserID: u.UserID,
43+
Email: u.Email,
44+
CreatedAt: u.CreatedAt,
45+
HasToken: u.UpToken.Valid && u.UpToken.String != "",
46+
}, nil
4147
}
4248

4349
func (s *UserService) UpdateToken(ctx context.Context, userID uuid.UUID, token string) error {

go/utils/time.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ func Now() time.Time {
1818
}
1919

2020
func Today() time.Time {
21-
return Now().Truncate(24 * time.Hour)
21+
n := Now()
22+
return time.Date(n.Year(), n.Month(), n.Day(), 0, 0, 0, 0, Location)
2223
}
2324

2425
func ToDate(t time.Time) time.Time {
25-
return t.In(Location).Truncate(24 * time.Hour)
26+
l := t.In(Location)
27+
return time.Date(l.Year(), l.Month(), l.Day(), 0, 0, 0, 0, Location)
2628
}

web/src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ import Dashboard from './pages/Dashboard'
44
import BucketDetail from './pages/BucketDetail'
55
import Settings from './pages/Settings'
66
import Rules from './pages/Rules'
7+
import Onboarding from './pages/Onboarding'
78

89
export default function App() {
910
return (
1011
<BrowserRouter>
1112
<Routes>
13+
<Route path="onboarding" element={<Onboarding />} />
1214
<Route element={<Layout />}>
1315
<Route index element={<Dashboard />} />
1416
<Route path="buckets/:id" element={<BucketDetail />} />

web/src/lib/api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export interface User {
22
user_id: string
33
email: string
44
created_at: string
5+
has_token: boolean
56
}
67

78
export interface Cover {

web/src/pages/Dashboard.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ export default function Dashboard() {
145145
queryFn: api.getTransactBalance,
146146
})
147147

148+
const { data: me } = useQuery({ queryKey: ['user'], queryFn: api.getUser })
149+
150+
useEffect(() => {
151+
if (me && !me.has_token) {
152+
navigate('/onboarding', { replace: true })
153+
}
154+
}, [me, navigate])
155+
148156
useEffect(() => {
149157
setOrderedBuckets(buckets)
150158
}, [buckets])

0 commit comments

Comments
 (0)