@@ -3,6 +3,7 @@ package usecase
33import (
44 "context"
55 "encoding/json"
6+ "fmt"
67 "os"
78 "path/filepath"
89 "strings"
@@ -97,26 +98,32 @@ func (s *LicenseService) evaluate() domain.License {
9798 if err != nil {
9899 return domain .Community () // no license installed → community
99100 }
101+ lic , err := s .validateAndParse (envelope )
102+ if err != nil {
103+ _ = catcher .Error ("billing: license invalid" , err , nil )
104+ return domain .Community ()
105+ }
106+ return lic
107+ }
100108
109+ func (s * LicenseService ) validateAndParse (envelope []byte ) (domain.License , error ) {
101110 instanceID := s .instanceID ()
102111 if instanceID == "" || s .publicKey == "" || s .salt == "" {
103- return domain .Community ( )
112+ return domain.License {}, fmt . Errorf ( "license verification not configured" )
104113 }
105114
106115 decrypted , err := lm .DecryptAndVerifyFromBase64 (strings .TrimSpace (string (envelope )), []string {instanceID , s .salt }, s .publicKey )
107116 if err != nil {
108- _ = catcher .Error ("billing: license decrypt/verify failed" , err , nil )
109- return domain .Community ()
117+ return domain.License {}, fmt .Errorf ("decrypt/verify failed: %w" , err )
110118 }
111119
112120 var inner licenseInner
113121 if err := json .Unmarshal ([]byte (decrypted ), & inner ); err != nil {
114- _ = catcher .Error ("billing: cannot parse license payload" , err , nil )
115- return domain .Community ()
122+ return domain.License {}, fmt .Errorf ("cannot parse license payload: %w" , err )
116123 }
117124
118125 if time .Now ().After (inner .ExpiresAt ) {
119- return domain .Community () // expired → community
126+ return domain.License {}, fmt . Errorf ( "license expired at %s" , inner . ExpiresAt . Format ( time . RFC3339 ))
120127 }
121128
122129 return domain.License {
@@ -125,7 +132,26 @@ func (s *LicenseService) evaluate() domain.License {
125132 Datasources : inner .Datasources ,
126133 Type : inner .Type ,
127134 ExpiresAt : inner .ExpiresAt ,
135+ }, nil
136+ }
137+
138+ func (s * LicenseService ) Replace (envelope []byte ) (domain.License , error ) {
139+ if _ , err := s .validateAndParse (envelope ); err != nil {
140+ return domain.License {}, fmt .Errorf ("%w: %v" , domain .ErrInvalidLicense , err )
141+ }
142+ if err := s .writeLicenseFile (envelope ); err != nil {
143+ return domain.License {}, fmt .Errorf ("billing: cannot write license file: %w" , err )
144+ }
145+ return s .Refresh (), nil
146+ }
147+
148+ func (s * LicenseService ) writeLicenseFile (envelope []byte ) error {
149+ data := []byte (strings .TrimSpace (string (envelope )) + "\n " )
150+ tmp := s .licenseFile + ".tmp"
151+ if err := os .WriteFile (tmp , data , 0o600 ); err != nil {
152+ return err
128153 }
154+ return os .Rename (tmp , s .licenseFile )
129155}
130156
131157func (s * LicenseService ) instanceID () string {
0 commit comments