-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
170 lines (150 loc) · 6.32 KB
/
Copy pathmain.go
File metadata and controls
170 lines (150 loc) · 6.32 KB
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
package main
import (
"context"
"fmt"
dbclient "ayo/internal/clients/db"
"ayo/internal/clients/storage"
"ayo/internal/features/auth"
"ayo/internal/features/dbconfig"
"ayo/internal/features/home"
"ayo/internal/features/masterkey"
"ayo/internal/features/recovery"
"ayo/internal/features/settings"
"ayo/internal/features/upload"
"ayo/internal/platform/queue"
"github.com/wailsapp/wails/v2"
"github.com/wailsapp/wails/v2/pkg/options"
"github.com/wailsapp/wails/v2/pkg/options/assetserver"
"github.com/wailsapp/wails/v2/pkg/options/mac"
)
// App is the root Wails-bound struct. It provides a minimal bridge between the
// webview frontend and the Go runtime (e.g. the application context).
type App struct {
ctx context.Context
}
// NewApp creates a new App application struct
func NewApp() *App {
return &App{}
}
// storageValidator adapts the storage package's provider validation to the
// settings service's ProviderValidator interface, keeping settings decoupled
// from the storage implementation.
type storageValidator struct{}
func (storageValidator) Validate(key settings.CloudKey) error {
return storage.Validate(key)
}
// startup is called when the app starts. The context is saved
// so we can call the runtime methods
func (a *App) startup(ctx context.Context) {
a.ctx = ctx
}
// Greet returns a greeting for the given name
func (a *App) Greet(name string) string {
return fmt.Sprintf("Hello %s, It's show time!", name)
}
func main() {
// Create an instance of the app structure
app := NewApp()
// There is no global database: each account has its own database (SQLite
// file or PostgreSQL server), stored encrypted in the OS keyring and opened
// by the auth service on login. The shared connection holder lets the
// queue/upload repositories serve whichever user is currently signed in.
conn := dbclient.NewConnection()
// Wire up the internal services. The auth service is the keystone: it owns
// the in-memory session, the master key and the active database connection,
// and is injected into the settings service (which needs the session to
// gate access and the master key to encrypt/decrypt stored settings).
// Database credentials are persisted in the OS keyring through the dbconfig
// feature. The encrypted master-key material can likewise live in the OS
// keyring (account-scoped "mkey_{username}") or in the users table; the
// masterkey repository is the keyring side of that choice, and the auth
// service migrates between the two via Get/SetMasterKeyStorage.
dbconfigRepository := dbconfig.NewRepository()
masterkeyRepository := masterkey.NewRepository()
authService := auth.NewService(conn, dbconfigRepository, masterkeyRepository)
// Recovery service: native save dialogs for downloading the recovery key.
recoveryService := recovery.NewService()
// Settings service: stores per-user settings in the OS keyring, encrypted
// with the session master key. Provider configs are validated through the
// storage package before saving.
settingsRepository := settings.NewRepository()
settingsService := settings.NewService(authService, authService, storageValidator{}, settingsRepository)
// Queue service: persistent SQLite-backed job queue shared across features.
// It resolves the signed-in user's database connection per operation.
queueService := queue.NewService(conn)
// Storage client: the local filesystem backend the upload feature reads and
// writes its own runtime files (encrypted staging, downloads) and local
// shards through. S3 clients for cloud shards are created on demand from the
// user's configured AWS keys; both implement the same storage.Client
// interface. Remote backends (Azure Blob, GCP) can be added the same way.
fileClient := storage.NewLocalFilesystem()
// Upload service: native file selection + enqueues one job per uploaded
// file into the queue. The processor encrypts each file, splits it into
// Reed-Solomon shards using the erasure-coding settings, and persists the
// stored-file record and its shards to the uploads/chunks tables of the
// signed-in user's database.
uploadRepository := upload.NewRepository(conn)
uploadService := upload.NewService(authService, settingsService, queueService, uploadRepository, fileClient)
// Home service: aggregation (recent files, storage totals, provider count,
// erasure-coding setup), the paginated drive listing/search, the edit action
// and storage-usage read for the Home screen. It owns the read-side queries
// of the uploads/chunks tables and delegates the shared reads (GetUpload,
// GetChunks) to the upload repository, so the data layer is implemented
// exactly once, and reads settings through the settings service.
homeRepository := home.NewRepository(conn, uploadRepository)
homeService := home.NewService(authService, homeRepository, settingsService, uploadService)
// Create application with options. Anything passed to Bind is exposed to
// the frontend as generated JavaScript bindings under
// frontend/wailsjs/go/, so changing a bound method requires a
// wails dev / wails build to regenerate them.
err := wails.Run(&options.App{
Title: "ayo",
Width: 1100,
Height: 768,
// Frameless: true,
AssetServer: &assetserver.Options{
// The compiled frontend (frontend/dist) is embedded into the binary
// via assets.go.
Assets: assets,
},
BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1},
OnStartup: func(ctx context.Context) {
app.startup(ctx)
// Only services that need the Wails context receive it here.
recoveryService.Startup(ctx)
uploadService.Startup(ctx)
settingsService.Startup(ctx)
},
DisableResize: false,
Mac: &mac.Options{
TitleBar: &mac.TitleBar{
TitlebarAppearsTransparent: false,
HideTitle: false,
HideTitleBar: false,
FullSizeContent: false,
UseToolbar: false,
HideToolbarSeparator: true,
},
Appearance: mac.NSAppearanceNameDarkAqua,
WebviewIsTransparent: false,
WindowIsTranslucent: false,
About: &mac.AboutInfo{
Title: "ayo",
Message: "A Wails Application",
Icon: nil,
},
},
// Every service listed here is callable from the React frontend.
Bind: []interface{}{
app,
authService,
recoveryService,
settingsService,
uploadService,
homeService,
},
})
if err != nil {
println("Error:", err.Error())
}
}