diff --git a/pkg/debrid/providers/alldebrid/alldebrid.go b/pkg/debrid/providers/alldebrid/alldebrid.go index d1b8797..8e60307 100644 --- a/pkg/debrid/providers/alldebrid/alldebrid.go +++ b/pkg/debrid/providers/alldebrid/alldebrid.go @@ -302,7 +302,7 @@ func (ad *AllDebrid) GetFileDownloadLinks(t *types.Torrent) error { for _, file := range t.Files { go func(file types.File) { defer wg.Done() - link, err := ad.GetDownloadLink(t, &file) + link, _, err := ad.GetDownloadLink(t, &file) if err != nil { errCh <- err return @@ -337,7 +337,7 @@ func (ad *AllDebrid) GetFileDownloadLinks(t *types.Torrent) error { links[link.Link] = link } // Update the files with download links - ad.accounts.SetDownloadLinks(links) + ad.accounts.SetDownloadLinks(nil, links) // Check for errors for err := range errCh { @@ -350,7 +350,7 @@ func (ad *AllDebrid) GetFileDownloadLinks(t *types.Torrent) error { return nil } -func (ad *AllDebrid) GetDownloadLink(t *types.Torrent, file *types.File) (*types.DownloadLink, error) { +func (ad *AllDebrid) GetDownloadLink(t *types.Torrent, file *types.File) (*types.DownloadLink, *types.Account, error) { url := fmt.Sprintf("%s/link/unlock", ad.Host) query := gourl.Values{} query.Add("link", file.Link) @@ -358,22 +358,21 @@ func (ad *AllDebrid) GetDownloadLink(t *types.Torrent, file *types.File) (*types req, _ := http.NewRequest(http.MethodGet, url, nil) resp, err := ad.client.MakeRequest(req) if err != nil { - return nil, err + return nil, nil, err } var data DownloadLink if err = json.Unmarshal(resp, &data); err != nil { - return nil, err + return nil, nil, err } if data.Error != nil { - return nil, fmt.Errorf("error getting download link: %s", data.Error.Message) + return nil, nil, fmt.Errorf("error getting download link: %s", data.Error.Message) } link := data.Data.Link if link == "" { - return nil, fmt.Errorf("download link is empty") + return nil, nil, fmt.Errorf("download link is empty") } now := time.Now() - account := ad.accounts.Current() return &types.DownloadLink{ Link: file.Link, DownloadLink: link, @@ -382,9 +381,7 @@ func (ad *AllDebrid) GetDownloadLink(t *types.Torrent, file *types.File) (*types Filename: file.Name, Generated: now, ExpiresAt: now.Add(ad.autoExpiresLinksAfter), - Token: account.Token, - MaskedToken: account.MaskedToken, - }, nil + }, nil, nil } func (ad *AllDebrid) GetTorrents() ([]*types.Torrent, error) { diff --git a/pkg/debrid/providers/debridlink/debrid_link.go b/pkg/debrid/providers/debridlink/debrid_link.go index 55766f3..afebd81 100644 --- a/pkg/debrid/providers/debridlink/debrid_link.go +++ b/pkg/debrid/providers/debridlink/debrid_link.go @@ -247,7 +247,7 @@ func (dl *DebridLink) UpdateTorrent(t *types.Torrent) error { t.Files[f.Name] = file } - dl.accounts.SetDownloadLinks(links) + dl.accounts.SetDownloadLinks(nil, links) return nil } @@ -287,7 +287,6 @@ func (dl *DebridLink) SubmitMagnet(t *types.Torrent) (*types.Torrent, error) { links := make(map[string]*types.DownloadLink) now := time.Now() - account := dl.accounts.Current() for _, f := range data.Files { file := types.File{ TorrentId: t.Id, @@ -304,14 +303,12 @@ func (dl *DebridLink) SubmitMagnet(t *types.Torrent) (*types.Torrent, error) { DownloadLink: f.DownloadURL, Generated: now, ExpiresAt: now.Add(dl.autoExpiresLinksAfter), - Token: account.Token, - MaskedToken: account.MaskedToken, } links[file.Link] = link file.DownloadLink = link t.Files[f.Name] = file } - dl.accounts.SetDownloadLinks(links) + dl.accounts.SetDownloadLinks(nil, links) return t, nil } @@ -359,7 +356,7 @@ func (dl *DebridLink) RefreshDownloadLinks() error { return nil } -func (dl *DebridLink) GetDownloadLink(t *types.Torrent, file *types.File) (*types.DownloadLink, error) { +func (dl *DebridLink) GetDownloadLink(t *types.Torrent, file *types.File) (*types.DownloadLink, *types.Account, error) { return dl.accounts.GetDownloadLink(file.Link) } @@ -410,7 +407,6 @@ func (dl *DebridLink) getTorrents(page, perPage int) ([]*types.Torrent, error) { if len(data) == 0 { return torrents, nil } - account := dl.accounts.Current() for _, t := range data { if t.Status != 100 { continue @@ -448,8 +444,6 @@ func (dl *DebridLink) getTorrents(page, perPage int) ([]*types.Torrent, error) { DownloadLink: f.DownloadURL, Generated: now, ExpiresAt: now.Add(dl.autoExpiresLinksAfter), - Token: account.Token, - MaskedToken: account.MaskedToken, } links[file.Link] = link file.DownloadLink = link @@ -457,7 +451,7 @@ func (dl *DebridLink) getTorrents(page, perPage int) ([]*types.Torrent, error) { } torrents = append(torrents, torrent) } - dl.accounts.SetDownloadLinks(links) + dl.accounts.SetDownloadLinks(nil, links) return torrents, nil } diff --git a/pkg/debrid/providers/realdebrid/realdebrid.go b/pkg/debrid/providers/realdebrid/realdebrid.go index 491545d..1fc45df 100644 --- a/pkg/debrid/providers/realdebrid/realdebrid.go +++ b/pkg/debrid/providers/realdebrid/realdebrid.go @@ -195,7 +195,7 @@ func (r *RealDebrid) handleRarArchive(t *types.Torrent, data torrentInfo, select r.logger.Info().Msgf("RAR file detected, unpacking: %s", t.Name) linkFile := &types.File{TorrentId: t.Id, Link: data.Links[0]} - downloadLinkObj, err := r.GetDownloadLink(t, linkFile) + downloadLinkObj, account, err := r.GetDownloadLink(t, linkFile) if err != nil { r.logger.Debug().Err(err).Msgf("Error getting download link for RAR file: %s. Falling back to single file representation.", t.Name) @@ -244,7 +244,7 @@ func (r *RealDebrid) handleRarArchive(t *types.Torrent, data torrentInfo, select return r.handleRarFallback(t, data) } r.logger.Info().Msgf("Unpacked RAR archive for torrent: %s with %d files", t.Name, len(files)) - r.accounts.SetDownloadLink(downloadLinkObj) + r.accounts.SetDownloadLink(account, downloadLinkObj) return files, nil } @@ -591,7 +591,7 @@ func (r *RealDebrid) GetFileDownloadLinks(t *types.Torrent) error { go func(file types.File) { defer wg.Done() - link, err := r.GetDownloadLink(t, &file) + link, account, err := r.GetDownloadLink(t, &file) if err != nil { mu.Lock() if firstErr == nil { @@ -610,7 +610,7 @@ func (r *RealDebrid) GetFileDownloadLinks(t *types.Torrent) error { } file.DownloadLink = link - r.accounts.SetDownloadLink(link) + r.accounts.SetDownloadLink(account, link) mu.Lock() files[file.Name] = file @@ -703,8 +703,6 @@ func (r *RealDebrid) getDownloadLink(account *types.Account, file *types.File) ( } now := time.Now() return &types.DownloadLink{ - MaskedToken: account.MaskedToken, - Token: account.Token, Filename: data.Filename, Size: data.Filesize, Link: data.Link, @@ -715,13 +713,14 @@ func (r *RealDebrid) getDownloadLink(account *types.Account, file *types.File) ( } -func (r *RealDebrid) GetDownloadLink(t *types.Torrent, file *types.File) (*types.DownloadLink, error) { +func (r *RealDebrid) GetDownloadLink(t *types.Torrent, file *types.File) (*types.DownloadLink, *types.Account, error) { + accounts := r.accounts.Active() for _, account := range accounts { downloadLink, err := r.getDownloadLink(account, file) if err == nil { - return downloadLink, nil + return downloadLink, account, nil } retries := 0 @@ -730,16 +729,16 @@ func (r *RealDebrid) GetDownloadLink(t *types.Torrent, file *types.File) (*types retries = 5 } else { // If the error is not traffic exceeded, return the error - return nil, err + return nil, account, err } backOff := 1 * time.Second for retries > 0 { downloadLink, err = r.getDownloadLink(account, file) if err == nil { - return downloadLink, nil + return downloadLink, account, nil } if !errors.Is(err, utils.TrafficExceededError) { - return nil, err + return nil, account, err } // Add a delay before retrying time.Sleep(backOff) @@ -747,7 +746,7 @@ func (r *RealDebrid) GetDownloadLink(t *types.Torrent, file *types.File) (*types retries-- } } - return nil, fmt.Errorf("realdebrid API error: download link not found") + return nil, nil, fmt.Errorf("realdebrid API error: used all active accounts") } func (r *RealDebrid) getTorrents(offset int, limit int) (int, []*types.Torrent, error) { @@ -873,7 +872,7 @@ func (r *RealDebrid) RefreshDownloadLinks() error { offset += len(dl) } - r.accounts.SetDownloadLinks(links) + r.accounts.SetDownloadLinks(account, links) } return nil } @@ -983,7 +982,7 @@ func (r *RealDebrid) SyncAccounts() error { } for _, account := range r.accounts.All() { if err := r.syncAccount(account); err != nil { - r.logger.Error().Err(err).Str("account", account.MaskedToken).Msgf("Error syncing account %s", account.Username) + r.logger.Error().Err(err).Msgf("Error syncing account %s", account.Username) continue // Skip this account and continue with the next } } diff --git a/pkg/debrid/providers/torbox/torbox.go b/pkg/debrid/providers/torbox/torbox.go index fee176b..384be3b 100644 --- a/pkg/debrid/providers/torbox/torbox.go +++ b/pkg/debrid/providers/torbox/torbox.go @@ -412,7 +412,7 @@ func (tb *Torbox) GetFileDownloadLinks(t *types.Torrent) error { for _, file := range t.Files { go func() { defer wg.Done() - link, err := tb.GetDownloadLink(t, &file) + link, _, err := tb.GetDownloadLink(t, &file) if err != nil { errCh <- err return @@ -440,7 +440,7 @@ func (tb *Torbox) GetFileDownloadLinks(t *types.Torrent) error { // Collect download links for link := range linkCh { if link != nil { - tb.accounts.SetDownloadLink(link) + tb.accounts.SetDownloadLink(nil, link) } } @@ -455,7 +455,7 @@ func (tb *Torbox) GetFileDownloadLinks(t *types.Torrent) error { return nil } -func (tb *Torbox) GetDownloadLink(t *types.Torrent, file *types.File) (*types.DownloadLink, error) { +func (tb *Torbox) GetDownloadLink(t *types.Torrent, file *types.File) (*types.DownloadLink, *types.Account, error) { url := fmt.Sprintf("%s/api/torrents/requestdl/", tb.Host) query := gourl.Values{} query.Add("torrent_id", t.Id) @@ -471,7 +471,7 @@ func (tb *Torbox) GetDownloadLink(t *types.Torrent, file *types.File) (*types.Do Str("torrent_id", t.Id). Str("file_id", file.Id). Msg("Failed to make request to Torbox API") - return nil, err + return nil, nil, err } var data DownloadLinksResponse @@ -481,7 +481,7 @@ func (tb *Torbox) GetDownloadLink(t *types.Torrent, file *types.File) (*types.Do Str("torrent_id", t.Id). Str("file_id", file.Id). Msg("Failed to unmarshal Torbox API response") - return nil, err + return nil, nil, err } if data.Data == nil { @@ -492,7 +492,7 @@ func (tb *Torbox) GetDownloadLink(t *types.Torrent, file *types.File) (*types.Do Interface("error", data.Error). Str("detail", data.Detail). Msg("Torbox API returned no data") - return nil, fmt.Errorf("error getting download links") + return nil, nil, fmt.Errorf("error getting download links") } link := *data.Data @@ -501,7 +501,7 @@ func (tb *Torbox) GetDownloadLink(t *types.Torrent, file *types.File) (*types.Do Str("torrent_id", t.Id). Str("file_id", file.Id). Msg("Torbox API returned empty download link") - return nil, fmt.Errorf("error getting download links") + return nil, nil, fmt.Errorf("error getting download links") } now := time.Now() @@ -511,11 +511,9 @@ func (tb *Torbox) GetDownloadLink(t *types.Torrent, file *types.File) (*types.Do Id: file.Id, Generated: now, ExpiresAt: now.Add(tb.autoExpiresLinksAfter), - Token: tb.APIKey, - MaskedToken: utils.Mask(tb.APIKey), } - return downloadLink, nil + return downloadLink, nil, nil } func (tb *Torbox) GetDownloadingStatus() []string { diff --git a/pkg/debrid/store/download_link.go b/pkg/debrid/store/download_link.go index 3c621c9..50f8de5 100644 --- a/pkg/debrid/store/download_link.go +++ b/pkg/debrid/store/download_link.go @@ -30,21 +30,22 @@ func (r *downloadLinkRequest) Wait() (string, error) { return r.result, r.err } -func (c *Cache) GetDownloadLink(torrentName, filename, fileLink string) (*types.DownloadLink, error) { +func (c *Cache) GetDownloadLink(torrentName, filename, fileLink string) (string, error) { // Check link cache - if dl, err := c.checkDownloadLink(fileLink); dl != nil && err == nil { + if dl, err := c.checkDownloadLink(fileLink); dl != "" && err == nil { return dl, nil } dl, err := c.fetchDownloadLink(torrentName, filename, fileLink) if err != nil { - return dl, err + return "", err } if dl == nil || dl.DownloadLink == "" { - return nil, fmt.Errorf("download link is empty for %s in torrent %s", filename, torrentName) + err = fmt.Errorf("download link is empty for %s in torrent %s", filename, torrentName) + return "", err } - return dl, nil + return dl.DownloadLink, err } func (c *Cache) fetchDownloadLink(torrentName, filename, fileLink string) (*types.DownloadLink, error) { @@ -85,10 +86,11 @@ func (c *Cache) fetchDownloadLink(torrentName, filename, fileLink string) (*type } c.logger.Trace().Msgf("Getting download link for %s(%s)", filename, file.Link) - downloadLink, err := c.client.GetDownloadLink(ct.Torrent, &file) + downloadLink, account, err := c.client.GetDownloadLink(ct.Torrent, &file) if err != nil { if errors.Is(err, utils.HosterUnavailableError) { c.logger.Trace(). + Str("account", account.Username). Str("filename", filename). Str("torrent_id", ct.Id). Msg("Hoster unavailable, attempting to reinsert torrent") @@ -103,7 +105,7 @@ func (c *Cache) fetchDownloadLink(torrentName, filename, fileLink string) (*type return nil, fmt.Errorf("file %s not found in reinserted torrent %s", filename, torrentName) } // Retry getting the download link - downloadLink, err = c.client.GetDownloadLink(ct.Torrent, &file) + downloadLink, account, err = c.client.GetDownloadLink(ct.Torrent, &file) if err != nil { return nil, fmt.Errorf("retry failed to get download link: %w", err) } @@ -123,7 +125,7 @@ func (c *Cache) fetchDownloadLink(torrentName, filename, fileLink string) (*type } // Set link to cache - go c.client.Accounts().SetDownloadLink(downloadLink) + go c.client.Accounts().SetDownloadLink(account, downloadLink) return downloadLink, nil } @@ -134,30 +136,25 @@ func (c *Cache) GetFileDownloadLinks(t CachedTorrent) { } } -func (c *Cache) checkDownloadLink(link string) (*types.DownloadLink, error) { +func (c *Cache) checkDownloadLink(link string) (string, error) { - dl, err := c.client.Accounts().GetDownloadLink(link) + dl, _, err := c.client.Accounts().GetDownloadLink(link) if err != nil { - return nil, err + return "", err } if !c.downloadLinkIsInvalid(dl.DownloadLink) { - return dl, nil + return dl.DownloadLink, nil } - return nil, fmt.Errorf("download link not found for %s", link) + return "", fmt.Errorf("download link not found for %s", link) } -func (c *Cache) MarkDownloadLinkAsInvalid(link string, downloadLink *types.DownloadLink, reason string) { - c.invalidDownloadLinks.Store(downloadLink.DownloadLink, reason) +func (c *Cache) MarkDownloadLinkAsInvalid(link, downloadLink, reason string) { + c.invalidDownloadLinks.Store(downloadLink, reason) // Remove the download api key from active if reason == "bandwidth_exceeded" { // Disable the account account, err := c.client.Accounts().GetAccountFromLink(link) if err != nil { - maskedToken := "" - if account != nil { - maskedToken = account.MaskedToken - } - c.logger.Warn().Err(err).Str("account", maskedToken).Str("link", link).Msg("Failed to mark download link as invalid") return } c.client.Accounts().Disable(account) diff --git a/pkg/debrid/types/account.go b/pkg/debrid/types/account.go index 793da4e..b095bd8 100644 --- a/pkg/debrid/types/account.go +++ b/pkg/debrid/types/account.go @@ -1,9 +1,7 @@ package types import ( - "fmt" "github.com/sirrobot01/decypharr/internal/config" - "github.com/sirrobot01/decypharr/internal/utils" "slices" "sync" "sync/atomic" @@ -39,7 +37,6 @@ type Account struct { Disabled bool InUse bool Token string `json:"token"` - MaskedToken string `json:"masked_token"` links map[string]*DownloadLink mu sync.RWMutex TrafficUsed int64 `json:"traffic_used"` // Traffic used in bytes @@ -98,12 +95,13 @@ func (a *Accounts) Current() *Account { return current } current = activeAccounts[0] - return a.setCurrent(current) + a.setCurrent(current) + return current } -func (a *Accounts) setCurrent(account *Account) *Account { +func (a *Accounts) setCurrent(account *Account) { if account == nil { - return nil + return } // Set every account InUse to false a.accounts.Range(func(key, value interface{}) bool { @@ -116,24 +114,25 @@ func (a *Accounts) setCurrent(account *Account) *Account { }) account.InUse = true a.current.Store(account) - return account } func (a *Accounts) Disable(account *Account) { account.Disabled = true - account.InUse = false a.accounts.Store(account.Token, account) current := a.getCurrent() if current.Equals(account) { var newCurrent *Account - activeAccounts := a.Active() - if len(activeAccounts) > 0 { - newCurrent = activeAccounts[0] - } else { - newCurrent = a.All()[0] - } + + a.accounts.Range(func(key, value interface{}) bool { + acc, ok := value.(*Account) + if ok && !acc.Disabled { + newCurrent = acc + return false // Break the loop + } + return true // Continue the loop + }) a.setCurrent(newCurrent) } } @@ -156,20 +155,19 @@ func (a *Accounts) Reset() { a.setCurrent(current) } -func (a *Accounts) GetDownloadLink(fileLink string) (*DownloadLink, error) { +func (a *Accounts) GetDownloadLink(fileLink string) (*DownloadLink, *Account, error) { current := a.Current() if current == nil { - return nil, NoActiveAccountsError + return nil, nil, NoActiveAccountsError } - dl, ok := current.GetDownloadLink(fileLink) + dl, ok := current.getLink(fileLink) if !ok { - return nil, NoDownloadLinkError + return nil, current, NoDownloadLinkError } - if !dl.Valid() { - return nil, fmt.Errorf("invalid download link: %s", dl.Link) + if err := dl.Valid(); err != nil { + return nil, current, err } - dl.Token = current.Token - return dl, nil + return dl, current, nil } func (a *Accounts) GetAccountFromLink(fileLink string) (*Account, error) { @@ -177,7 +175,7 @@ func (a *Accounts) GetAccountFromLink(fileLink string) (*Account, error) { if currentAccount == nil { return nil, NoActiveAccountsError } - dl, ok := currentAccount.GetDownloadLink(fileLink) + dl, ok := currentAccount.getLink(fileLink) if !ok { return nil, NoDownloadLinkError } @@ -188,22 +186,13 @@ func (a *Accounts) GetAccountFromLink(fileLink string) (*Account, error) { } // SetDownloadLink sets the download link for the current account -func (a *Accounts) SetDownloadLink(dl *DownloadLink) { +func (a *Accounts) SetDownloadLink(account *Account, dl *DownloadLink) { if dl == nil { return } - var account *Account - // Get account from link token - if dl.Token != "" { - - if acc, ok := a.accounts.Load(dl.Token); ok { - account = acc.(*Account) - } - } if account == nil { account = a.getCurrent() } - account.setLink(dl.Link, dl) } @@ -221,11 +210,12 @@ func (a *Accounts) GetLinksCount() int { return a.Current().LinksCount() } -func (a *Accounts) SetDownloadLinks(links map[string]*DownloadLink) { - if a.Current() == nil { - return +func (a *Accounts) SetDownloadLinks(account *Account, links map[string]*DownloadLink) { + if account == nil { + account = a.Current() } - a.Current().setLinks(links) + account.setLinks(links) + a.accounts.Store(account.Token, account) } func (a *Accounts) Update(account *Account) { @@ -237,11 +227,10 @@ func (a *Accounts) Update(account *Account) { func newAccount(debridName, token string, index int) *Account { return &Account{ - Debrid: debridName, - Token: token, - MaskedToken: utils.Mask(token), - Order: index, - links: make(map[string]*DownloadLink), + Debrid: debridName, + Token: token, + Order: index, + links: make(map[string]*DownloadLink), } } @@ -252,7 +241,7 @@ func (a *Account) Equals(other *Account) bool { return a.Token == other.Token && a.Debrid == other.Debrid } -func (a *Account) GetDownloadLink(fileLink string) (*DownloadLink, bool) { +func (a *Account) getLink(fileLink string) (*DownloadLink, bool) { a.mu.RLock() defer a.mu.RUnlock() dl, ok := a.links[a.sliceFileLink(fileLink)] @@ -284,7 +273,7 @@ func (a *Account) setLinks(links map[string]*DownloadLink) { a.mu.Lock() defer a.mu.Unlock() for _, dl := range links { - if !dl.Valid() { + if err := dl.Valid(); err != nil { continue } a.links[a.sliceFileLink(dl.Link)] = dl diff --git a/pkg/debrid/types/client.go b/pkg/debrid/types/client.go index 41aea21..6aeff7f 100644 --- a/pkg/debrid/types/client.go +++ b/pkg/debrid/types/client.go @@ -8,7 +8,7 @@ type Client interface { SubmitMagnet(tr *Torrent) (*Torrent, error) CheckStatus(tr *Torrent) (*Torrent, error) GetFileDownloadLinks(tr *Torrent) error - GetDownloadLink(tr *Torrent, file *File) (*DownloadLink, error) + GetDownloadLink(tr *Torrent, file *File) (*DownloadLink, *Account, error) DeleteTorrent(torrentId string) error IsAvailable(infohashes []string) map[string]bool GetDownloadUncached() bool diff --git a/pkg/debrid/types/torrent.go b/pkg/debrid/types/torrent.go index dd45f6c..b5de18e 100644 --- a/pkg/debrid/types/torrent.go +++ b/pkg/debrid/types/torrent.go @@ -176,19 +176,17 @@ type DownloadLink struct { Generated time.Time `json:"generated"` Size int64 `json:"size"` Id string `json:"id"` - ExpiresAt time.Time `json:"expires_at"` - MaskedToken string `json:"masked_token"` - Token string `json:"token"` // The token or api key used to generate this link + ExpiresAt time.Time } -func (dl *DownloadLink) Valid() bool { +func (dl *DownloadLink) Valid() error { if dl.DownloadLink == "" { - return false + return EmptyDownloadLinkError } if dl.ExpiresAt.IsZero() || dl.ExpiresAt.Before(time.Now()) { - return false + return DownloadLinkExpiredError } - return true + return nil } func (dl *DownloadLink) String() string { diff --git a/pkg/server/debug.go b/pkg/server/debug.go index cded44d..c889463 100644 --- a/pkg/server/debug.go +++ b/pkg/server/debug.go @@ -123,11 +123,21 @@ func (s *Server) handleStats(w http.ResponseWriter, r *http.Request) { accounts := client.Accounts().All() accountDetails := make([]map[string]any, 0) for _, account := range accounts { + // Mask token - show first 8 characters and last 4 characters + maskedToken := "" + if len(account.Token) > 12 { + maskedToken = account.Token[:8] + "****" + account.Token[len(account.Token)-4:] + } else if len(account.Token) > 8 { + maskedToken = account.Token[:4] + "****" + account.Token[len(account.Token)-2:] + } else { + maskedToken = "****" + } + accountDetail := map[string]any{ "order": account.Order, "disabled": account.Disabled, "in_use": account.InUse, - "masked_token": account.MaskedToken, + "token_masked": maskedToken, "username": account.Username, "traffic_used": account.TrafficUsed, "links_count": account.LinksCount(), diff --git a/pkg/web/templates/stats.html b/pkg/web/templates/stats.html index fabdf7b..9163a76 100644 --- a/pkg/web/templates/stats.html +++ b/pkg/web/templates/stats.html @@ -384,13 +384,12 @@
${account.username || 'No username'}