Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions internal/api/handshake.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"time"

"connectrpc.com/connect"
"github.com/spf13/viper"
"github.com/zalando/go-keyring"

apiv1 "github.com/focusd-so/focusd/gen/api/v1"
Expand Down Expand Up @@ -44,6 +45,7 @@ func PerformHandshake(ctx context.Context, client apiv1connect.ApiServiceClient)

req := connect.NewRequest(&apiv1.DeviceHandshakeRequest{
DeviceFingerprint: deviceFingerPrint,
AppVersion: viper.GetString("app_version"),
})

req.Header().Set("X-Timestamp", timestamp)
Expand Down
16 changes: 15 additions & 1 deletion internal/api/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (

"connectrpc.com/connect"
"gorm.io/gorm"
"gorm.io/gorm/clause"

apiv1 "github.com/focusd-so/focusd/gen/api/v1"
"github.com/focusd-so/focusd/gen/api/v1/apiv1connect"
Expand All @@ -26,7 +27,7 @@ type ServiceImpl struct {
}

func NewServiceImpl(gormDB *gorm.DB, productIDs map[apiv1.CheckoutProduct]string) (*ServiceImpl, error) {
if err := gormDB.AutoMigrate(&User{}, &UserDevice{}, &HandshakeNonce{}, &LLMProxyUsage{}); err != nil {
if err := gormDB.AutoMigrate(&User{}, &UserDevice{}, &HandshakeNonce{}, &LLMProxyUsage{}, &AppVersionLog{}); err != nil {
return nil, fmt.Errorf("failed to migrate database: %w", err)
}

Expand Down Expand Up @@ -57,6 +58,19 @@ func (s *ServiceImpl) DeviceHandshake(ctx context.Context, req *connect.Request[
return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("db error: %w", err))
}

if req.Msg.AppVersion != "" {
now := time.Now().Unix()
s.gormDB.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "user_id"}, {Name: "device_fingerprint"}, {Name: "version"}},
DoUpdates: clause.AssignmentColumns([]string{"timestamp"}),
}).Create(&AppVersionLog{
UserID: user.ID,
DeviceFingerprint: req.Msg.DeviceFingerprint,
Version: req.Msg.AppVersion,
Timestamp: now,
})
}

sessionToken, err := MintToken(user, user.Role)
if err != nil {
return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("failed to mint session: %w", err))
Expand Down
12 changes: 12 additions & 0 deletions internal/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,15 @@ type LLMProxyUsage struct {
func (l *LLMProxyUsage) TableName() string {
return "llm_proxy_usage"
}

type AppVersionLog struct {
ID int64 `gorm:"primaryKey;autoIncrement" json:"id"`
UserID int64 `gorm:"not null;uniqueIndex:idx_user_device_version" json:"user_id"`
DeviceFingerprint string `gorm:"not null;uniqueIndex:idx_user_device_version" json:"device_fingerprint"`
Version string `gorm:"not null;uniqueIndex:idx_user_device_version" json:"version"`
Timestamp int64 `gorm:"not null" json:"timestamp"`
}

func (a *AppVersionLog) TableName() string {
return "app_version_log"
}
2 changes: 2 additions & 0 deletions internal/identity/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
apiv1 "github.com/focusd-so/focusd/gen/api/v1"
"github.com/focusd-so/focusd/gen/api/v1/apiv1connect"
"github.com/focusd-so/focusd/internal/native"
"github.com/spf13/viper"
)

var (
Expand Down Expand Up @@ -81,6 +82,7 @@ func PerformHandshake(ctx context.Context, client apiv1connect.ApiServiceClient)

req := connect.NewRequest(&apiv1.DeviceHandshakeRequest{
DeviceFingerprint: deviceFingerPrint,
AppVersion: viper.GetString("app_version"),
})

req.Header().Set("X-Timestamp", timestamp)
Expand Down
1 change: 1 addition & 0 deletions internal/settings/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ func NewService(configDir string) (*Service, error) {
viper.SetDefault("history_retention_days", 30)
viper.SetDefault("distraction_allowance_minutes", 60)
viper.SetDefault("custom_rules_js", []string{})
viper.SetDefault("app_version", "dev")

// Config file settings
viper.SetConfigName("config")
Expand Down
7 changes: 5 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/gorilla/websocket"
"github.com/spf13/viper"
_ "github.com/tursodatabase/libsql-client-go/libsql"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
Expand All @@ -29,12 +30,12 @@ import (
"gorm.io/gorm"

"github.com/focusd-so/focusd/internal/api"
"github.com/focusd-so/focusd/internal/fs"
"github.com/focusd-so/focusd/internal/sandbox"
"github.com/focusd-so/focusd/internal/extension"
"github.com/focusd-so/focusd/internal/fs"
"github.com/focusd-so/focusd/internal/identity"
"github.com/focusd-so/focusd/internal/native"
"github.com/focusd-so/focusd/internal/nativemessaging"
"github.com/focusd-so/focusd/internal/sandbox"
"github.com/focusd-so/focusd/internal/settings"
"github.com/focusd-so/focusd/internal/updater"
"github.com/focusd-so/focusd/internal/usage"
Expand Down Expand Up @@ -97,6 +98,8 @@ func main() {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

viper.Set("app_version", Version)

extensionSessionAPIKey, err := generateSessionAPIKey()
if err != nil {
log.Fatalf("failed to generate extension session API key: %v", err)
Expand Down
Loading