Initial commit: Open sourcing all of the Maple Open Technologies code.

This commit is contained in:
Bartlomiej Mika 2025-12-02 14:33:08 -05:00
commit 755d54a99d
2010 changed files with 448675 additions and 0 deletions

View file

@ -0,0 +1,28 @@
package collection
// Repository defines the data access operations for collections
type Repository interface {
// Create stores a new collection record
Create(collection *Collection) error
// Get retrieves a collection by its ID
Get(id string) (*Collection, error)
// Update modifies an existing collection record
Update(collection *Collection) error
// Delete removes a collection record by its ID
Delete(id string) error
// List returns all collection records
List() ([]*Collection, error)
// ListByParent returns all collections with a specific parent ID
ListByParent(parentID string) ([]*Collection, error)
// ListRoot returns all root-level collections (no parent)
ListRoot() ([]*Collection, error)
// Exists checks if a collection with the given ID exists
Exists(id string) (bool, error)
}

View file

@ -0,0 +1,98 @@
package collection
import "time"
// Collection represents a collection (folder/album) stored locally with sync capabilities.
type Collection struct {
// Identifiers (from cloud)
ID string `json:"id"`
ParentID string `json:"parent_id,omitempty"`
OwnerID string `json:"owner_id"` // UserID from cloud
// Encryption data (from cloud)
EncryptedCollectionKey string `json:"encrypted_collection_key"`
Nonce string `json:"nonce"`
// Collection metadata (from cloud - name is decrypted client-side)
Name string `json:"name"` // Decrypted name
Description string `json:"description,omitempty"` // Optional description
// CustomIcon is the decrypted custom icon for this collection.
// Empty string means use default folder/album icon.
// Contains either an emoji character (e.g., "📷") or "icon:<identifier>" for predefined icons.
CustomIcon string `json:"custom_icon,omitempty"`
// Statistics (from cloud)
TotalFiles int `json:"total_files"`
TotalSizeInBytes int64 `json:"total_size_in_bytes"`
// Sharing info (from cloud)
PermissionLevel string `json:"permission_level,omitempty"` // read_only, read_write, admin
IsOwner bool `json:"is_owner"`
OwnerName string `json:"owner_name,omitempty"`
OwnerEmail string `json:"owner_email,omitempty"`
// Sync tracking (local only)
SyncStatus SyncStatus `json:"sync_status"`
LastSyncedAt time.Time `json:"last_synced_at,omitempty"`
// State from cloud
State string `json:"state"` // active, deleted
// Timestamps (from cloud)
CreatedAt time.Time `json:"created_at"`
ModifiedAt time.Time `json:"modified_at"`
}
// SyncStatus defines the synchronization status of a collection
type SyncStatus int
const (
// SyncStatusCloudOnly indicates the collection metadata is synced from cloud
SyncStatusCloudOnly SyncStatus = iota
// SyncStatusSynced indicates the collection is fully synchronized
SyncStatusSynced
)
// String returns a human-readable string representation of the sync status
func (s SyncStatus) String() string {
switch s {
case SyncStatusCloudOnly:
return "cloud_only"
case SyncStatusSynced:
return "synced"
default:
return "unknown"
}
}
// Collection state constants
const (
// StateActive indicates the collection is active
StateActive = "active"
// StateDeleted indicates the collection is deleted
StateDeleted = "deleted"
)
// Permission level constants
const (
PermissionReadOnly = "read_only"
PermissionReadWrite = "read_write"
PermissionAdmin = "admin"
)
// IsDeleted returns true if the collection is marked as deleted
func (c *Collection) IsDeleted() bool {
return c.State == StateDeleted
}
// CanWrite returns true if the user has write permissions
func (c *Collection) CanWrite() bool {
return c.IsOwner || c.PermissionLevel == PermissionReadWrite || c.PermissionLevel == PermissionAdmin
}
// CanAdmin returns true if the user has admin permissions
func (c *Collection) CanAdmin() bool {
return c.IsOwner || c.PermissionLevel == PermissionAdmin
}

View file

@ -0,0 +1,58 @@
package file
// SyncStatus defines the synchronization status of a file
type SyncStatus int
const (
// SyncStatusLocalOnly indicates the file exists only locally (not uploaded to cloud)
SyncStatusLocalOnly SyncStatus = iota
// SyncStatusCloudOnly indicates the file exists only in the cloud (metadata synced, content not downloaded)
SyncStatusCloudOnly
// SyncStatusSynced indicates the file exists both locally and in the cloud and is synchronized
SyncStatusSynced
// SyncStatusModifiedLocally indicates the file exists in both places but has local changes pending upload
SyncStatusModifiedLocally
)
// String returns a human-readable string representation of the sync status
func (s SyncStatus) String() string {
switch s {
case SyncStatusLocalOnly:
return "local_only"
case SyncStatusCloudOnly:
return "cloud_only"
case SyncStatusSynced:
return "synced"
case SyncStatusModifiedLocally:
return "modified_locally"
default:
return "unknown"
}
}
// Storage mode constants define which file versions to keep locally
const (
// StorageModeEncryptedOnly - Only keep encrypted version locally (most secure)
StorageModeEncryptedOnly = "encrypted_only"
// StorageModeDecryptedOnly - Only keep decrypted version locally (not recommended)
StorageModeDecryptedOnly = "decrypted_only"
// StorageModeHybrid - Keep both encrypted and decrypted versions (default, convenient)
StorageModeHybrid = "hybrid"
)
// File state constants
const (
// StatePending is the initial state of a file before it is uploaded
StatePending = "pending"
// StateActive indicates that the file is fully uploaded and ready for use
StateActive = "active"
// StateDeleted marks the file as deleted
StateDeleted = "deleted"
)

View file

@ -0,0 +1,28 @@
package file
// Repository defines the data access operations for files
type Repository interface {
// Create stores a new file record
Create(file *File) error
// Get retrieves a file by its ID
Get(id string) (*File, error)
// Update modifies an existing file record
Update(file *File) error
// Delete removes a file record by its ID
Delete(id string) error
// List returns all file records
List() ([]*File, error)
// ListByCollection returns all files belonging to a specific collection
ListByCollection(collectionID string) ([]*File, error)
// ListByStatus returns all files with a specific sync status
ListByStatus(status SyncStatus) ([]*File, error)
// Exists checks if a file with the given ID exists
Exists(id string) (bool, error)
}

View file

@ -0,0 +1,88 @@
package file
import "time"
// File represents a file stored locally with sync capabilities.
// This model combines cloud metadata with local storage tracking.
type File struct {
// Identifiers (from cloud)
ID string `json:"id"`
CollectionID string `json:"collection_id"`
OwnerID string `json:"owner_id"` // UserID from cloud
// Encryption data (from cloud API response)
EncryptedFileKey EncryptedFileKeyData `json:"encrypted_file_key"`
FileKeyNonce string `json:"file_key_nonce"`
EncryptedMetadata string `json:"encrypted_metadata"`
MetadataNonce string `json:"metadata_nonce"`
FileNonce string `json:"file_nonce"`
// File sizes (from cloud)
EncryptedSizeInBytes int64 `json:"encrypted_file_size_in_bytes"`
DecryptedSizeInBytes int64 `json:"decrypted_size_in_bytes,omitempty"`
// Local storage paths (local only)
EncryptedFilePath string `json:"encrypted_file_path,omitempty"`
FilePath string `json:"file_path,omitempty"`
ThumbnailPath string `json:"thumbnail_path,omitempty"`
// Decrypted metadata (local only - populated after decryption)
Name string `json:"name,omitempty"`
MimeType string `json:"mime_type,omitempty"`
Metadata *FileMetadata `json:"metadata,omitempty"`
// Sync tracking (local only)
SyncStatus SyncStatus `json:"sync_status"`
LastSyncedAt time.Time `json:"last_synced_at,omitempty"`
// State from cloud
State string `json:"state"` // pending, active, deleted
StorageMode string `json:"storage_mode"` // encrypted_only, hybrid, decrypted_only
Version int `json:"version"` // Cloud version for conflict resolution
// Timestamps (from cloud)
CreatedAt time.Time `json:"created_at"`
ModifiedAt time.Time `json:"modified_at"`
// Thumbnail URL (from cloud, for remote access)
ThumbnailURL string `json:"thumbnail_url,omitempty"`
}
// EncryptedFileKeyData matches the cloud API structure exactly
type EncryptedFileKeyData struct {
Ciphertext string `json:"ciphertext"`
Nonce string `json:"nonce"`
}
// FileMetadata represents decrypted file metadata (populated after decryption)
type FileMetadata struct {
Name string `json:"name"`
MimeType string `json:"mime_type"`
Size int64 `json:"size"`
FileExtension string `json:"file_extension"`
}
// IsCloudOnly returns true if the file only exists in the cloud
func (f *File) IsCloudOnly() bool {
return f.SyncStatus == SyncStatusCloudOnly
}
// IsSynced returns true if the file is synchronized between local and cloud
func (f *File) IsSynced() bool {
return f.SyncStatus == SyncStatusSynced
}
// IsLocalOnly returns true if the file only exists locally
func (f *File) IsLocalOnly() bool {
return f.SyncStatus == SyncStatusLocalOnly
}
// HasLocalContent returns true if the file has local content (not just metadata)
func (f *File) HasLocalContent() bool {
return f.FilePath != "" || f.EncryptedFilePath != ""
}
// IsDeleted returns true if the file is marked as deleted
func (f *File) IsDeleted() bool {
return f.State == StateDeleted
}

View file

@ -0,0 +1,16 @@
package session
// Repository interface defines data access operations for sessions
type Repository interface {
// Save stores a session
Save(session *Session) error
// Get retrieves the current session
Get() (*Session, error)
// Delete removes the current session
Delete() error
// Exists checks if a session exists
Exists() (bool, error)
}

View file

@ -0,0 +1,30 @@
package session
import "time"
// Session represents a user authentication session (domain entity)
type Session struct {
UserID string
Email string
AccessToken string
RefreshToken string
ExpiresAt time.Time
CreatedAt time.Time
// Encrypted user data for password verification (stored during login)
Salt string // Base64 encoded salt for password derivation
EncryptedMasterKey string // Base64 encoded encrypted master key
EncryptedPrivateKey string // Base64 encoded encrypted private key
PublicKey string // Base64 encoded public key
KDFAlgorithm string // Key derivation algorithm: "PBKDF2-SHA256"
}
// IsExpired checks if the session has expired
func (s *Session) IsExpired() bool {
return time.Now().After(s.ExpiresAt)
}
// IsValid checks if the session is valid (not expired and has tokens)
func (s *Session) IsValid() bool {
return !s.IsExpired() && s.AccessToken != "" && s.RefreshToken != ""
}

View file

@ -0,0 +1,13 @@
package syncstate
// Repository defines the data access operations for sync state
type Repository interface {
// Get retrieves the current sync state
Get() (*SyncState, error)
// Save persists the sync state
Save(state *SyncState) error
// Reset clears the sync state (for fresh sync)
Reset() error
}

View file

@ -0,0 +1,77 @@
package syncstate
import "time"
// SyncState tracks the synchronization progress for collections and files.
// It stores cursors from the API for incremental sync and timestamps for tracking.
type SyncState struct {
// Timestamps for tracking when sync occurred
LastCollectionSync time.Time `json:"last_collection_sync"`
LastFileSync time.Time `json:"last_file_sync"`
// Cursors from API responses (used for pagination)
CollectionCursor string `json:"collection_cursor,omitempty"`
FileCursor string `json:"file_cursor,omitempty"`
// Sync completion flags
CollectionSyncComplete bool `json:"collection_sync_complete"`
FileSyncComplete bool `json:"file_sync_complete"`
}
// NewSyncState creates a new empty SyncState
func NewSyncState() *SyncState {
return &SyncState{}
}
// IsCollectionSyncComplete returns true if all collections have been synced
func (s *SyncState) IsCollectionSyncComplete() bool {
return s.CollectionSyncComplete
}
// IsFileSyncComplete returns true if all files have been synced
func (s *SyncState) IsFileSyncComplete() bool {
return s.FileSyncComplete
}
// IsFullySynced returns true if both collections and files are fully synced
func (s *SyncState) IsFullySynced() bool {
return s.CollectionSyncComplete && s.FileSyncComplete
}
// ResetCollectionSync resets the collection sync state for a fresh sync
func (s *SyncState) ResetCollectionSync() {
s.CollectionCursor = ""
s.CollectionSyncComplete = false
s.LastCollectionSync = time.Time{}
}
// ResetFileSync resets the file sync state for a fresh sync
func (s *SyncState) ResetFileSync() {
s.FileCursor = ""
s.FileSyncComplete = false
s.LastFileSync = time.Time{}
}
// Reset resets both collection and file sync states
func (s *SyncState) Reset() {
s.ResetCollectionSync()
s.ResetFileSync()
}
// UpdateCollectionSync updates the collection sync state after a sync operation
func (s *SyncState) UpdateCollectionSync(cursor string, hasMore bool) {
s.CollectionCursor = cursor
s.CollectionSyncComplete = !hasMore
if !hasMore {
s.LastCollectionSync = time.Now()
}
}
// UpdateFileSync updates the file sync state after a sync operation
func (s *SyncState) UpdateFileSync(cursor string, hasMore bool) {
s.FileCursor = cursor
s.FileSyncComplete = !hasMore
if !hasMore {
s.LastFileSync = time.Now()
}
}

View file

@ -0,0 +1,10 @@
package user
// Repository defines the interface for user data persistence
type Repository interface {
Save(user *User) error
GetByID(id string) (*User, error)
GetByEmail(email string) (*User, error)
Delete(id string) error
Exists(id string) (bool, error)
}

View file

@ -0,0 +1,19 @@
package user
import "time"
// User represents a MapleFile user profile stored locally
type User struct {
ID string
Email string
FirstName string
LastName string
StorageQuotaBytes int64
CreatedAt time.Time
UpdatedAt time.Time
}
// IsValid checks if the user has the minimum required fields
func (u *User) IsValid() bool {
return u.ID != "" && u.Email != ""
}