feat: expand companion platform, device controls, and memoir workflows
ci / verify (push) Canceled after 0s

Add customer and operator login, BLE provisioning, device fleet controls, call memory, memoir generation, and refreshed family and maintenance portals. Include API contracts, migrations, firmware sources, tests, assets, and deployment documentation.
This commit is contained in:
Codex Local
2026-10-08 10:06:44 +08:00
parent 98fb2965d0
commit bf1233d5df
861 changed files with 94614 additions and 3209 deletions
+93
View File
@@ -0,0 +1,93 @@
package devicefleet
import (
"context"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"errors"
"io"
"net/url"
"strings"
"time"
"github.com/jackc/pgx/v5"
)
const (
downloadTokenBytes = 16
downloadTicketTTL = 30 * time.Minute
)
var ErrDownloadTicketUnavailable = errors.New("firmware download ticket is unavailable")
type DownloadGrant struct {
ObjectRef string
Size int64
SHA256 string
CreatedAt time.Time
ExpiresAt time.Time
}
func newDownloadTicket(baseURL string) (string, []byte, string, time.Time, error) {
raw := make([]byte, downloadTokenBytes)
if _, err := rand.Read(raw); err != nil {
return "", nil, "", time.Time{}, err
}
token := base64.RawURLEncoding.EncodeToString(raw)
digest := sha256.Sum256([]byte(token))
address, err := shortDownloadURL(baseURL, token)
if err != nil {
return "", nil, "", time.Time{}, err
}
return token, digest[:], address, time.Now().UTC().Add(downloadTicketTTL), nil
}
func shortDownloadURL(baseURL, token string) (string, error) {
parsed, err := url.Parse(strings.TrimSpace(baseURL))
if err != nil || parsed.Host == "" || parsed.User != nil || (parsed.Scheme != "https" && parsed.Scheme != "http") || (parsed.Path != "" && parsed.Path != "/") || parsed.RawQuery != "" || parsed.Fragment != "" {
return "", errors.New("firmware download base URL must be an HTTP(S) origin")
}
parsed.Path = "/f/" + token
return parsed.String(), nil
}
func downloadTokenHash(token string) ([]byte, error) {
raw, err := base64.RawURLEncoding.DecodeString(token)
if err != nil || len(raw) != downloadTokenBytes || base64.RawURLEncoding.EncodeToString(raw) != token {
return nil, ErrDownloadTicketUnavailable
}
digest := sha256.Sum256([]byte(token))
return digest[:], nil
}
func (s *Service) ResolveDownload(ctx context.Context, token string) (DownloadGrant, error) {
var grant DownloadGrant
digest, err := downloadTokenHash(strings.TrimSpace(token))
if err != nil {
return grant, err
}
err = s.Pool.QueryRow(ctx, `
SELECT f.object_ref,f.size,f.sha256,f.created_at,t.expires_at
FROM fleet_firmware_download_ticket t
JOIN fleet_firmware f ON f.id=t.release_id
LEFT JOIN fleet_ota o ON o.id=t.ota_id
WHERE t.token_hash=$1
AND t.revoked_at IS NULL
AND t.expires_at>now()
AND (t.ota_id IS NULL OR
(o.status='pending' AND o.created_at>now()-interval '30 seconds') OR
(o.status='accepted' AND o.created_at>now()-interval '20 minutes'))
AND f.status='READY'`, digest).Scan(&grant.ObjectRef, &grant.Size, &grant.SHA256, &grant.CreatedAt, &grant.ExpiresAt)
if errors.Is(err, pgx.ErrNoRows) {
return DownloadGrant{}, ErrDownloadTicketUnavailable
}
return grant, err
}
func (s *Service) OpenDownload(ctx context.Context, grant DownloadGrant) (io.ReadSeekCloser, error) {
if s.Store == nil || grant.ObjectRef == "" {
return nil, ErrDownloadTicketUnavailable
}
return s.Store.OpenDownload(ctx, grant.ObjectRef)
}