style: remove hyphens from compound adjectives in comments and messages
Remove hyphens from compound adjectives such as "logged-in", "one-time", "password-protected", "full-height", "multi-file", and "S3-compatible" in comments, test error messages, and UI labels to improve readability and consistency.
This commit is contained in:
@@ -68,7 +68,7 @@ func TestLoggedInUploadStoresOwnerAndAnonymousUploadDoesNot(t *testing.T) {
|
||||
}
|
||||
}
|
||||
if !foundOwned {
|
||||
t.Fatalf("logged-in upload did not store owner id %q", user.ID)
|
||||
t.Fatalf("logged in upload did not store owner id %q", user.ID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,7 +674,7 @@ func TestAPIDocsHeaderReflectsLoggedInUser(t *testing.T) {
|
||||
body := response.Body.String()
|
||||
header := body[:strings.Index(body, "<main")]
|
||||
if !strings.Contains(header, "Dashboard") || strings.Contains(header, "Sign in") || strings.Contains(header, "Health") {
|
||||
t.Fatalf("api header did not reflect logged-in state: %s", body)
|
||||
t.Fatalf("api header did not reflect logged in state: %s", body)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -775,7 +775,7 @@ func TestAdminOverviewRendersInlineBarDimensions(t *testing.T) {
|
||||
}
|
||||
body := response.Body.String()
|
||||
if !strings.Contains(body, `style="height: 150px"`) {
|
||||
t.Fatalf("admin overview did not render a full-height pixel bar: %s", body)
|
||||
t.Fatalf("admin overview did not render a full height pixel bar: %s", body)
|
||||
}
|
||||
if !strings.Contains(body, `data-height-px="150"`) || !strings.Contains(body, `data-chart-value=`) {
|
||||
t.Fatalf("admin overview did not render chart fallback data attributes: %s", body)
|
||||
|
||||
@@ -398,7 +398,7 @@ func buildAdminOverview(boxes []services.AdminBox, stats services.AdminStats) ad
|
||||
statusBars := []adminStatBar{
|
||||
{Label: "Active", Value: strconv.Itoa(activeBoxes), RawValue: activeBoxes, WidthPercent: percentOf(activeBoxes, maxStatusValue)},
|
||||
{Label: "Expired", Value: strconv.Itoa(stats.ExpiredBoxes), RawValue: stats.ExpiredBoxes, WidthPercent: percentOf(stats.ExpiredBoxes, maxStatusValue)},
|
||||
{Label: "Password-protected", Value: strconv.Itoa(stats.ProtectedBoxes), RawValue: stats.ProtectedBoxes, WidthPercent: percentOf(stats.ProtectedBoxes, maxStatusValue)},
|
||||
{Label: "password protected", Value: strconv.Itoa(stats.ProtectedBoxes), RawValue: stats.ProtectedBoxes, WidthPercent: percentOf(stats.ProtectedBoxes, maxStatusValue)},
|
||||
}
|
||||
|
||||
return adminOverview{
|
||||
@@ -1934,7 +1934,7 @@ func (a *App) storageConfigFromForm(r *http.Request, provider string) services.S
|
||||
|
||||
func adminStorageProviderOptions() []adminStorageProviderView {
|
||||
return []adminStorageProviderView{
|
||||
{Provider: services.StorageProviderS3, Label: "S3 Bucket", Description: "Generic S3-compatible object storage.", Icon: "cloud"},
|
||||
{Provider: services.StorageProviderS3, Label: "S3 Bucket", Description: "Generic S3 compatible object storage.", Icon: "cloud"},
|
||||
{Provider: services.StorageProviderContabo, Label: "Contabo Object Storage", Description: "Contabo COS with TLS and path-style lookup locked on.", Icon: "cloud"},
|
||||
{Provider: services.StorageProviderSFTP, Label: "SFTP", Description: "SSH file transfer to a server or NAS.", Icon: "database"},
|
||||
{Provider: services.StorageProviderSMB, Label: "Samba / SMB", Description: "Windows share or network attached storage.", Icon: "folder"},
|
||||
|
||||
@@ -59,7 +59,7 @@ func (a *App) ShareXAnonymousConfig(w http.ResponseWriter, r *http.Request) {
|
||||
"RequestURL": a.cfg.BaseURL + "/api/v1/upload",
|
||||
"Headers": map[string]string{
|
||||
"Accept": "application/json",
|
||||
// Group a multi-file selection (sent as back-to-back requests) into
|
||||
// Group a multiple file selection (sent as back to back requests) into
|
||||
// one box. Remove this header for one box per file.
|
||||
uploadBatchHeader: "sharex",
|
||||
},
|
||||
|
||||
@@ -127,7 +127,7 @@ func (a *App) RegisterRoutes(mux *http.ServeMux) {
|
||||
mux.HandleFunc("GET /d/{boxID}/manage/{token}", a.ManageBox)
|
||||
mux.HandleFunc("POST /d/{boxID}/manage/{token}/delete", a.ManageDeleteBox)
|
||||
// GET variant so ShareX (which issues a GET to the configured DeletionURL)
|
||||
// can delete a box via its secret one-time delete token.
|
||||
// can delete a box via its secret one time delete token.
|
||||
mux.HandleFunc("GET /d/{boxID}/manage/{token}/delete", a.ManageDeleteBox)
|
||||
mux.HandleFunc("POST /d/{boxID}/unlock", a.UnlockBox)
|
||||
mux.HandleFunc("GET /d/{boxID}/zip", a.DownloadZip)
|
||||
|
||||
@@ -160,7 +160,7 @@ func (a *App) AccountSettings(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// CreateUserToken mints a new personal access token and renders the account
|
||||
// page with the one-time plaintext shown. The secret is never recoverable after
|
||||
// page with the one time plaintext shown. The secret is never recoverable after
|
||||
// this response.
|
||||
func (a *App) CreateUserToken(w http.ResponseWriter, r *http.Request) {
|
||||
user, ok := a.requireUser(w, r)
|
||||
|
||||
@@ -162,7 +162,7 @@ func (a *App) DownloadPage(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
pageURL := absoluteURL(r, fmt.Sprintf("/d/%s", box.ID))
|
||||
|
||||
// All user uploads are private/temporary — noindex by default.
|
||||
// All user uploads are private/temporary. noindex by default.
|
||||
robots := web.RobotsNone
|
||||
|
||||
a.renderPage(w, r, http.StatusOK, "download.html", web.PageData{
|
||||
|
||||
@@ -34,7 +34,7 @@ type mimeRule struct {
|
||||
icon fileIcon
|
||||
}
|
||||
|
||||
// fileIconSet is the loaded icon map: an extension lookup plus content-type
|
||||
// fileIconSet is the loaded icon map: an extension lookup plus Content-Type
|
||||
// rules and a fallback. It is built once at startup from icon-map.json.
|
||||
type fileIconSet struct {
|
||||
byExt map[string]fileIcon
|
||||
@@ -43,7 +43,7 @@ type fileIconSet struct {
|
||||
}
|
||||
|
||||
// loadFileIcons reads static/file-icons/icon-map.json and indexes it by
|
||||
// extension and content type so icons can be assigned at render time.
|
||||
// extension and Content-Type so icons can be assigned at render time.
|
||||
func loadFileIcons(staticDir string) (*fileIconSet, error) {
|
||||
data, err := os.ReadFile(filepath.Join(staticDir, "file-icons", "icon-map.json"))
|
||||
if err != nil {
|
||||
@@ -111,8 +111,8 @@ func validateFileIconPath(staticDir, theme, name string) error {
|
||||
}
|
||||
|
||||
// lookup resolves a file's icon from its name (extension) first, falling back to
|
||||
// its content type, then to the default icon. Extension wins because stored
|
||||
// content types are often the generic application/octet-stream.
|
||||
// its Content-Type, then to the default icon. Extension wins because stored
|
||||
// Content-Types are often the generic application/octet-stream.
|
||||
func (s *fileIconSet) lookup(name, contentType string) fileIcon {
|
||||
if s == nil {
|
||||
return fileIcon{}
|
||||
|
||||
@@ -15,7 +15,7 @@ func (a *App) RobotsTxt(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Fprintf(w, `User-agent: *
|
||||
Allow: /
|
||||
|
||||
# Private routes — do not crawl
|
||||
# Private routes. do not crawl
|
||||
Disallow: /admin/
|
||||
Disallow: /api/
|
||||
Disallow: /app/
|
||||
|
||||
@@ -552,7 +552,7 @@ func collageGrid(n int) (cols, rows int) {
|
||||
}
|
||||
|
||||
// drawCover scales src to completely fill dst, cropping the overflow (centred),
|
||||
// preserving aspect ratio — the CSS object-fit: cover equivalent.
|
||||
// preserving aspect ratio. the CSS object-fit: cover equivalent.
|
||||
func drawCover(dst *image.RGBA, cell image.Rectangle, src image.Image) {
|
||||
b := src.Bounds()
|
||||
iw, ih := b.Dx(), b.Dy()
|
||||
|
||||
@@ -91,7 +91,7 @@ func (a *App) homeExpiryOptions(settings services.UploadPolicySettings, user ser
|
||||
unlimited = true
|
||||
case loggedIn:
|
||||
maxDays = a.settingsService.EffectivePolicyForUser(settings, user).MaxDays
|
||||
// A negative per-user MaxDays override means unlimited retention.
|
||||
// A negative per user MaxDays override means unlimited retention.
|
||||
if maxDays < 0 {
|
||||
unlimited = true
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ func (a *App) createOrAppendBox(r *http.Request, user services.User, loggedIn bo
|
||||
}
|
||||
|
||||
// batchBoxMatches guards that a batched append only ever touches a box owned by
|
||||
// the same uploader (account for logged-in users, creator IP for anonymous).
|
||||
// the same uploader (account for logged in users, creator IP for anonymous).
|
||||
func (a *App) batchBoxMatches(box services.Box, user services.User, loggedIn bool, r *http.Request) bool {
|
||||
if loggedIn {
|
||||
return box.OwnerID == user.ID
|
||||
|
||||
@@ -7,11 +7,11 @@ import (
|
||||
|
||||
// uploadGroupWindow is how long after a batched upload a follow-up upload with
|
||||
// the same X-Warpbox-Batch value (and same account/IP) is folded into the same
|
||||
// box. ShareX sends a multi-file selection as separate back-to-back requests;
|
||||
// box. ShareX sends a multiple file selection as separate back to back requests;
|
||||
// the batch header lets it land them in one box.
|
||||
const uploadGroupWindow = 20 * time.Second
|
||||
|
||||
// uploadBatchHeader is the opt-in request header. Without it, uploads behave
|
||||
// uploadBatchHeader is the opt in request header. Without it, uploads behave
|
||||
// exactly as before (one box per request). With it, requests sharing the same
|
||||
// value (per account/IP) within uploadGroupWindow are grouped into one box.
|
||||
const uploadBatchHeader = "X-Warpbox-Batch"
|
||||
@@ -20,7 +20,7 @@ const uploadBatchHeader = "X-Warpbox-Batch"
|
||||
// can't grow without bound (one key per account/IP + batch value otherwise).
|
||||
const uploadGroupPruneInterval = 5 * time.Minute
|
||||
|
||||
// uploadGrouper tracks the most recent box per batch key so opt-in batched
|
||||
// uploadGrouper tracks the most recent box per batch key so opt in batched
|
||||
// uploads land in a single box. Each key has its own lock, which also serialises
|
||||
// that key's concurrent uploads so they append to the same box instead of racing
|
||||
// to create several.
|
||||
|
||||
@@ -51,17 +51,17 @@ func GenerateThumbnailsForBoxAsync(uploadService *services.UploadService, logger
|
||||
return
|
||||
}
|
||||
if services.BoxHasTrouble(box) {
|
||||
logger.Warn("thumbnail one-shot skipped trouble box", "source", "thumbnail", "severity", "warn", "code", 4206, "box_id", boxID, "error", services.BoxTroubleReason(box))
|
||||
logger.Warn("thumbnail one shot skipped trouble box", "source", "thumbnail", "severity", "warn", "code", 4206, "box_id", boxID, "error", services.BoxTroubleReason(box))
|
||||
return
|
||||
}
|
||||
|
||||
result, err := generateMissingThumbnailsForBox(uploadService, logger, box)
|
||||
if err != nil {
|
||||
logger.Warn("thumbnail one-shot job failed", "source", "thumbnail", "severity", "warn", "code", 4205, "box_id", boxID, "error", err.Error())
|
||||
logger.Warn("thumbnail one shot job failed", "source", "thumbnail", "severity", "warn", "code", 4205, "box_id", boxID, "error", err.Error())
|
||||
return
|
||||
}
|
||||
if result.Generated > 0 || result.Failed > 0 {
|
||||
logger.Info("thumbnail one-shot job complete", "source", "thumbnail", "severity", "user_activity", "code", 2205, "box_id", boxID, "generated", result.Generated, "failed", result.Failed)
|
||||
logger.Info("thumbnail one shot job complete", "source", "thumbnail", "severity", "user_activity", "code", 2205, "box_id", boxID, "generated", result.Generated, "failed", result.Failed)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ type Collection struct {
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
// APIToken is a long-lived personal access token. Only the SHA-256 hash of the
|
||||
// APIToken is a long lived personal access token. Only the SHA-256 hash of the
|
||||
// secret is stored; the plaintext is shown to the user exactly once at creation.
|
||||
type APIToken struct {
|
||||
ID string `json:"id"`
|
||||
@@ -131,7 +131,7 @@ type APIToken struct {
|
||||
LastUsedAt *time.Time `json:"lastUsedAt,omitempty"`
|
||||
}
|
||||
|
||||
// APITokenResult carries the one-time plaintext alongside the stored token.
|
||||
// APITokenResult carries the one time plaintext alongside the stored token.
|
||||
type APITokenResult struct {
|
||||
Token APIToken
|
||||
Plaintext string
|
||||
@@ -907,7 +907,7 @@ func validateUserPolicy(policy UserPolicy) error {
|
||||
return fmt.Errorf("active box override must be positive or -1 for unlimited")
|
||||
}
|
||||
if policy.ShortWindowRequests != nil && *policy.ShortWindowRequests <= 0 && *policy.ShortWindowRequests != -1 {
|
||||
return fmt.Errorf("short-window request override must be positive or -1 for unlimited")
|
||||
return fmt.Errorf("short window request override must be positive or -1 for unlimited")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ func TestAPITokenLifecycle(t *testing.T) {
|
||||
if result.Plaintext == "" || !strings.HasPrefix(result.Plaintext, apiTokenPrefix) {
|
||||
t.Fatalf("plaintext = %q, want %q prefix", result.Plaintext, apiTokenPrefix)
|
||||
}
|
||||
// The secret must never be stored in plaintext — only its hash.
|
||||
// The secret must never be stored in plaintext. only its hash.
|
||||
if strings.Contains(result.Token.TokenHash, result.Plaintext) || result.Token.TokenHash == result.Plaintext {
|
||||
t.Fatalf("stored token hash leaks the plaintext secret")
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ func (s *BanService) Match(ip string, now time.Time) (MatchedBan, bool, error) {
|
||||
now = now.UTC()
|
||||
var matched BanRecord
|
||||
var matchedKey []byte
|
||||
// Read-only scan first: the common case (no match) only takes a concurrent
|
||||
// read only scan first: the common case (no match) only takes a concurrent
|
||||
// read transaction, instead of grabbing the single bbolt write lock on every
|
||||
// request that flows through the ban middleware.
|
||||
err := s.db.View(func(tx *bbolt.Tx) error {
|
||||
|
||||
@@ -19,7 +19,7 @@ func ClientIPFromContext(r *http.Request) (string, bool) {
|
||||
}
|
||||
|
||||
// ClientIP resolves the effective client IP. When trustedProxies is empty,
|
||||
// forwarded headers are trusted for easy reverse-proxy/container defaults.
|
||||
// forwarded headers are trusted for easy reverse proxy/container defaults.
|
||||
func ClientIP(remoteAddr, forwardedFor, realIP string, trustedProxies []string) string {
|
||||
remoteIP := IPOnly(remoteAddr)
|
||||
if len(trustedProxies) == 0 || remoteTrusted(remoteIP, trustedProxies) {
|
||||
|
||||
@@ -455,7 +455,7 @@ func (s *SettingsService) validate(settings UploadPolicySettings) error {
|
||||
return fmt.Errorf("active box limits must be positive")
|
||||
}
|
||||
if settings.ShortWindowRequests <= 0 || settings.ShortWindowSeconds <= 0 {
|
||||
return fmt.Errorf("short-window rate limits must be positive")
|
||||
return fmt.Errorf("short window rate limits must be positive")
|
||||
}
|
||||
if settings.ResumableChunkSizeMB <= 0 {
|
||||
return fmt.Errorf("resumable chunk size must be positive")
|
||||
|
||||
@@ -306,7 +306,7 @@ func (s *UploadService) CreateBoxFromIncomingContext(ctx context.Context, files
|
||||
var expiresAt time.Time
|
||||
switch {
|
||||
case opts.ExpiresInMinutes < 0 || opts.MaxDays < 0:
|
||||
// "Forever" — a date far enough out that the box effectively never
|
||||
// "Forever". a date far enough out that the box effectively never
|
||||
// expires. No schema change; CanDownload/cleanup keep working as-is.
|
||||
expiresAt = now.AddDate(100, 0, 0)
|
||||
case opts.ExpiresInMinutes > 0:
|
||||
@@ -361,7 +361,7 @@ func (s *UploadService) CreateBoxFromIncomingContext(ctx context.Context, files
|
||||
return s.resultForBox(box, deleteToken), nil
|
||||
}
|
||||
|
||||
// AppendFiles adds files to an existing box (used to group a ShareX multi-file
|
||||
// AppendFiles adds files to an existing box (used to group a ShareX multiple file
|
||||
// selection into a single box). The box keeps its original expiry, password and
|
||||
// other settings; only the new files are written.
|
||||
func (s *UploadService) AppendFiles(boxID string, files []*multipart.FileHeader, opts UploadOptions) (UploadResult, error) {
|
||||
@@ -1099,7 +1099,7 @@ func (s *UploadService) resultForBox(box Box, deleteToken string) UploadResult {
|
||||
}
|
||||
|
||||
// The box-level thumbnail points at the most recently added file, so a
|
||||
// per-file ShareX upload previews the file it just sent.
|
||||
// per file ShareX upload previews the file it just sent.
|
||||
thumbnailURL := fmt.Sprintf("%s/d/%s/og-image.jpg", s.baseURL, box.ID)
|
||||
if len(files) > 0 {
|
||||
thumbnailURL = files[len(files)-1].ThumbnailURL
|
||||
|
||||
Reference in New Issue
Block a user