diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index efcf0c640..f7bfd1d9f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,7 +2,7 @@ There are many ways you can contribute to Fider. -- **Send us a Pull Request** on GitHub. Make sure you read our [Getting Started](#getting-started-with-fider-codebase) guide to learn how to setup the development environment; +- **Send us a Pull Request** on GitHub. Make sure you read our [Getting Started](#getting-started-with-fider-codebase) guide to learn how to set up the development environment; - **Translate Fider** to your language. See our [translation guide](/locale/README.md) to learn how to add a new language; - **Report issues** and bug reports on https://github.com/getfider/fider/issues; - **Give feedback** and vote on features you'd like to see at https://feedback.fider.io; @@ -41,7 +41,7 @@ If you know these technologies or would like to learn them, lucky you! This is t a fake SMTP server running at port **1025** and a UI (to check sent emails) at http://localhost:8025. The `.example.env` is already configured to use it. If you want to, you can edit `.env` file and configure the `EMAIL_*` environment variables with your own SMTP server details. If you don't have an SMTP server, you can either sign up for a [Mailgun account](https://www.mailgun.com/) (it's Free) or sign - up for a [Mailtrap account](https://mailtrap.io), which is a free SMTP mocking server. If you prefer not to setup an email service, keep + up for a [Mailtrap account](https://mailtrap.io), which is a free SMTP mocking server. If you prefer not to set up an email service, keep an eye on the server logs. Sometimes it's necessary to navigate to some URLs that are only sent by email, but are also written to the logs. #### 3. To start the application diff --git a/GUIDELINES.md b/GUIDELINES.md index ad250f3a0..76ec7ba11 100644 --- a/GUIDELINES.md +++ b/GUIDELINES.md @@ -39,4 +39,4 @@ Fider uses a combination of BEM and Utility Classes. - `is-`, `has-` are global style modifiers that have a broader impact. -- Utility classes do not have a preffix. +- Utility classes do not have a prefix. diff --git a/MODERATION.md b/MODERATION.md index 507368fce..d78876c1b 100644 --- a/MODERATION.md +++ b/MODERATION.md @@ -6,13 +6,13 @@ This document explains everything that needs to change in Fider to facilitate th ## Settings -This is a optional feature. Admins will be able to toggle this. This is done in the public/pages/Administration/pages/PrivacySettings.page.tsx page. Similar to how the other settings are controlled in this page. There needs to be a new column in the "tenants" database table called "is_moderation_enabled" to control this, so you're going to need a new migration file in migrations/ +This is an optional feature. Admins will be able to toggle this. This is done in the public/pages/Administration/pages/PrivacySettings.page.tsx page. Similar to how the other settings are controlled in this page. There needs to be a new column in the "tenants" database table called "is_moderation_enabled" to control this, so you're going to need a new migration file in migrations/ ## New posts and comments Posts and comments will need a new column "is_approved" to determine if the post or comment has been approved to be shown. Again, this will need adding to the migration. -When a new post or comment is added, if moderation is enabled then is_approved will be false, otherwise it will be true. New posts are added via public/pages/Home/components/ShareFeedback.tsx and comments via public/pages/ShowPost/components/CommentInput.tsx. +When a new post or comment is added, if moderation is enabled then is_approved will be false; otherwise, it will be true. New posts are added via public/pages/Home/components/ShareFeedback.tsx and comments via public/pages/ShowPost/components/CommentInput.tsx. Once added, the post is only visible to the person who added it (and admins, see below). When you view the post (or the comment) via public/pages/ShowPost/ShowPost.page.tsx, there needs to be a message to tell you that it's awaiting moderation. @@ -21,9 +21,9 @@ Once added, the post is only visible to the person who added it (and admins, see The "admin" section of fider looks like this (public/pages/Administration/components/AdminBasePage.tsx): ![alt text]() -There neeeds to be a new menu item on the left for "Moderation" +There needs to be a new menu item on the left for "Moderation" -Clicking on that presents you with a tablular view of all non-moderated posts and comments. +Clicking on that presents you with a tabular view of all non-moderated posts and comments. For each row, display the following columns: _ A checkbox to allow you to select multiple rows _ User's name and date of post (e.g. "Matt, 10 minutes ago") @@ -32,7 +32,7 @@ _ If comment: "New comment: " (truncated to 200 chars) _ If post: "New post: " _ Thumbs up button to approve \* Thumbs down button to decline -If you click the description for a post or comment, it will take you to the post, and if you clicked a comment, will highlight the comment (this is already supporeted, see how the public/pages/ShowPost/ShowPost.page.tsx page highlights comments). When you are an admin, and it's a post that's awaiting moderation, the in place of the voting button, we need 2 buttons - one to approve, one to decline. The same is true for comments, there should be an approve / decline set of buttons udner the comment. +If you click the description for a post or comment, it will take you to the post, and if you clicked a comment, will highlight the comment (this is already supported, see how the public/pages/ShowPost/ShowPost.page.tsx page highlights comments). When you are an admin, and it's a post that's awaiting moderation, the in place of the voting button, we need 2 buttons - one to approve, one to decline. The same is true for comments, there should be an approve / decline set of buttons under the comment. Declining a post or comment will delete it entirely. We should ask the user to confirm the action. @@ -50,7 +50,7 @@ We've decided to make some changes to the moderation admin: 1. Rather than have it part of the admin menu, remove the entry from the side menu in admin. Instead, we want an icon in the top Header (public/components/Header.tsx) that when clicked, takes you to the moderation admin page, without the side menu. Ideally the icon will have a little counter in the top-right of how many items are awaiting moderation. -2. We've decided to make the moderation less onourous to the admins by making some more changes: +2. We've decided to make the moderation less onerous to the admins by making some more changes: 2.1) As well as decline, you have another option - "decline and block". This option will decline the post or comment, and block the user who made it from posting again. We already have the ability to block users in Fider (see BlockUser in app/handlers/user.go), so we can hook into that. So if you had 1 user who had 5 posts and some comments, and you declined and blocked them, we would also decline all other posts and comments they made, and block them from posting again. diff --git a/app/actions/post.go b/app/actions/post.go index 75a4d9e68..385152f9f 100644 --- a/app/actions/post.go +++ b/app/actions/post.go @@ -236,7 +236,7 @@ func (action *AddNewComment) Validate(ctx context.Context, user *entity.User) *v return result } -// SetResponse represents the action to update an post response +// SetResponse represents the action to update a post response type SetResponse struct { Number int `route:"number"` Status enum.PostStatus `json:"status"` @@ -264,8 +264,8 @@ func (action *SetResponse) Validate(ctx context.Context, user *entity.User) *val result.AddFieldFailure("originalNumber", i18n.T(ctx, "validation.custom.selfduplicate")) } - getOriginaPost := &query.GetPostByNumber{Number: action.OriginalNumber} - err := bus.Dispatch(ctx, getOriginaPost) + getOriginalPost := &query.GetPostByNumber{Number: action.OriginalNumber} + err := bus.Dispatch(ctx, getOriginalPost) if err != nil { if errors.Cause(err) == app.ErrNotFound { result.AddFieldFailure("originalNumber", i18n.T(ctx, "validation.custom.originalpostnotfound")) @@ -274,8 +274,8 @@ func (action *SetResponse) Validate(ctx context.Context, user *entity.User) *val } } - if getOriginaPost.Result != nil { - action.Original = getOriginaPost.Result + if getOriginalPost.Result != nil { + action.Original = getOriginalPost.Result } } diff --git a/app/actions/tag.go b/app/actions/tag.go index 78628b954..6937c6336 100644 --- a/app/actions/tag.go +++ b/app/actions/tag.go @@ -93,7 +93,7 @@ func (action *DeleteTag) Validate(ctx context.Context, user *entity.User) *valid return validate.Success() } -// AssignUnassignTag is used to assign or remove a tag to/from an post +// AssignUnassignTag is used to assign or remove a tag to/from a post type AssignUnassignTag struct { Slug string `route:"slug"` Number int `route:"number"` diff --git a/app/actions/tenant.go b/app/actions/tenant.go index 7c957eb1a..aed39fa95 100644 --- a/app/actions/tenant.go +++ b/app/actions/tenant.go @@ -20,9 +20,9 @@ import ( // CreateTenant is the input model used to create a tenant type CreateTenant struct { - Token string `json:"token"` - Name string `json:"name"` - Email string `json:"email" format:"lower"` + Token string `json:"token"` + Name string `json:"name"` + Email string `json:"email" format:"lower"` VerificationKey string `json:"-"` TenantName string `json:"tenantName"` LegalAgreement bool `json:"legalAgreement"` @@ -290,7 +290,7 @@ func (action *UpdateTenantPrivacySettings) IsAuthorized(ctx context.Context, use // Validate if current model is valid func (action *UpdateTenantPrivacySettings) Validate(ctx context.Context, user *entity.User) *validate.Result { if action.IsPrivate && action.IsFeedEnabled { - return validate.Failed("Feed can not be enabled when set to private.") + return validate.Failed("Feed cannot be enabled when set to private.") } return validate.Success() } diff --git a/app/cmd/server.go b/app/cmd/server.go index b9c1ae12c..c7989022d 100644 --- a/app/cmd/server.go +++ b/app/cmd/server.go @@ -57,7 +57,7 @@ func RunServer() int { func startJobs(ctx context.Context) { c := cron.New() _ = c.AddJob(jobs.NewJob(ctx, "PurgeExpiredNotificationsJob", jobs.PurgeExpiredNotificationsJobHandler{})) - _ = c.AddJob(jobs.NewJob(ctx, "EmailSupressionJob", jobs.EmailSupressionJobHandler{})) + _ = c.AddJob(jobs.NewJob(ctx, "EmailSuppressionJob", jobs.EmailSuppressionJobHandler{})) c.Start() } diff --git a/app/handlers/images.go b/app/handlers/images.go index 6cdbd2cc0..b139eeac6 100644 --- a/app/handlers/images.go +++ b/app/handlers/images.go @@ -55,7 +55,7 @@ func LetterAvatar() web.HandlerFunc { } } -// Gravatar returns a gravatar picture of fallsback to letter avatar based on name +// Gravatar returns a gravatar picture or falls back to letter avatar based on name func Gravatar() web.HandlerFunc { return func(c *web.Context) error { id, err := c.ParamAsInt("id") diff --git a/app/handlers/oauth_roles_test.go b/app/handlers/oauth_roles_test.go index 55b554d70..acd7dd4fd 100644 --- a/app/handlers/oauth_roles_test.go +++ b/app/handlers/oauth_roles_test.go @@ -31,7 +31,7 @@ func TestHasAllowedRole_WhitespaceOnlyConfig_AllowsAll(t *testing.T) { func TestHasAllowedRole_NoRolesPath_SkipsCheck(t *testing.T) { // Provider without a roles path must always be allowed through, - // regardless of whether the user carries matching roles or not. + // regardless of whether or not the user carries matching roles. if !hasAllowedRole([]string{}, "", "ROLE_ADMIN") { t.Error("expected true when provider has no JSONUserRolesPath (check should be skipped)") } @@ -116,4 +116,3 @@ func TestHasAllowedRole_ConfigWithOnlyCommas_AllowsAll(t *testing.T) { t.Error("expected true when config contains only separators (no valid roles)") } } - diff --git a/app/handlers/post_test.go b/app/handlers/post_test.go index 59733b1a4..dc4a84e29 100644 --- a/app/handlers/post_test.go +++ b/app/handlers/post_test.go @@ -81,7 +81,7 @@ func TestDetailsHandler(t *testing.T) { Expect(code).Equals(http.StatusOK) } -func TestDetailsHandler_RedirectOnDifferentSlu(t *testing.T) { +func TestDetailsHandler_RedirectOnDifferentSlug(t *testing.T) { RegisterT(t) post := &entity.Post{Number: 1, Title: "My Post Title", Slug: "my-post-title"} diff --git a/app/jobs/email_supression_job.go b/app/jobs/email_supression_job.go index 5040fc21b..554a7f4b8 100644 --- a/app/jobs/email_supression_job.go +++ b/app/jobs/email_supression_job.go @@ -11,37 +11,37 @@ import ( "github.com/getfider/fider/app/pkg/log" ) -type EmailSupressionJobHandler struct { +type EmailSuppressionJobHandler struct { } -func (e EmailSupressionJobHandler) Schedule() string { +func (e EmailSuppressionJobHandler) Schedule() string { return "0 5 * * * *" // every hour at minute 5 } -func (e EmailSupressionJobHandler) Run(ctx Context) error { +func (e EmailSuppressionJobHandler) Run(ctx Context) error { startTime := ctx.LastSuccessfulRun if startTime == nil { twoDaysAgo := time.Now().AddDate(0, 0, -2) startTime = &twoDaysAgo } - q := &query.FetchRecentSupressions{ + q := &query.FetchRecentSuppressions{ StartTime: *startTime, } if err := bus.Dispatch(ctx, q); err != nil { - return errors.Wrap(err, "failed to fetch recent supressions") + return errors.Wrap(err, "failed to fetch recent suppressions") } - c := &cmd.SupressEmail{ + c := &cmd.SuppressEmail{ EmailAddresses: q.EmailAddresses, } if err := bus.Dispatch(ctx, c); err != nil { - return errors.Wrap(err, "failed to supress emails") + return errors.Wrap(err, "failed to suppress emails") } - log.Debugf(ctx, "@{Count} account(s) marked with supressed email", dto.Props{ - "Count": c.NumOfSupressedEmailAddresses, + log.Debugf(ctx, "@{Count} account(s) marked with suppressed email", dto.Props{ + "Count": c.NumOfSuppressedEmailAddresses, }) return nil diff --git a/app/jobs/email_supression_job_test.go b/app/jobs/email_supression_job_test.go index 25af3597b..fc328ac97 100644 --- a/app/jobs/email_supression_job_test.go +++ b/app/jobs/email_supression_job_test.go @@ -11,29 +11,29 @@ import ( "github.com/getfider/fider/app/pkg/bus" ) -func TestEmailSupressionJob_Schedule_IsCorrect(t *testing.T) { +func TestEmailSuppressionJob_Schedule_IsCorrect(t *testing.T) { RegisterT(t) - job := &jobs.EmailSupressionJobHandler{} + job := &jobs.EmailSuppressionJobHandler{} Expect(job.Schedule()).Equals("0 5 * * * *") } -func TestEmailSupressionJob_ShouldSupressRecentFailures(t *testing.T) { +func TestEmailSuppressionJob_ShouldSuppressRecentFailures(t *testing.T) { RegisterT(t) - bus.AddHandler(func(ctx context.Context, q *query.FetchRecentSupressions) error { + bus.AddHandler(func(ctx context.Context, q *query.FetchRecentSuppressions) error { q.EmailAddresses = []string{ "test1@gmail.com", "test2@gmail.com", } return nil }) - bus.AddHandler(func(ctx context.Context, c *cmd.SupressEmail) error { + bus.AddHandler(func(ctx context.Context, c *cmd.SuppressEmail) error { Expect(c.EmailAddresses).Equals([]string{"test1@gmail.com", "test2@gmail.com"}) return nil }) - job := &jobs.EmailSupressionJobHandler{} + job := &jobs.EmailSuppressionJobHandler{} err := job.Run(jobs.Context{ Context: context.Background(), }) diff --git a/app/models/cmd/notification.go b/app/models/cmd/notification.go index b65918605..a473b4f41 100644 --- a/app/models/cmd/notification.go +++ b/app/models/cmd/notification.go @@ -33,9 +33,9 @@ type RemoveSubscriber struct { User *entity.User } -type SupressEmail struct { +type SuppressEmail struct { EmailAddresses []string //Output - NumOfSupressedEmailAddresses int + NumOfSuppressedEmailAddresses int } diff --git a/app/models/entity/comment.go b/app/models/entity/comment.go index c1343cc5a..5fdfa56af 100644 --- a/app/models/entity/comment.go +++ b/app/models/entity/comment.go @@ -10,7 +10,7 @@ type ReactionCounts struct { IncludesMe bool `json:"includesMe"` } -// Comment represents an user comment on an post +// Comment represents a user comment on a post type Comment struct { ID int `json:"id"` Content string `json:"content"` diff --git a/app/models/entity/post.go b/app/models/entity/post.go index 3e2a93348..59f44e1d0 100644 --- a/app/models/entity/post.go +++ b/app/models/entity/post.go @@ -7,7 +7,7 @@ import ( "github.com/getfider/fider/app/models/enum" ) -//Post represents an post on a tenant board +//Post represents a post on a tenant board type Post struct { ID int `json:"id"` Number int `json:"number"` diff --git a/app/models/enum/avatar.go b/app/models/enum/avatar.go index 787d7cbb3..27cf5ee2f 100644 --- a/app/models/enum/avatar.go +++ b/app/models/enum/avatar.go @@ -34,7 +34,7 @@ func (t AvatarType) MarshalText() ([]byte, error) { return []byte(avatarTypesIDs[t]), nil } -// UnmarshalText parse string into a avatar type +// UnmarshalText parse string into an avatar type func (t *AvatarType) UnmarshalText(text []byte) error { *t = avatarTypesName[string(text)] return nil diff --git a/app/models/enum/notification.go b/app/models/enum/notification.go index 90a8fffaa..4a67ab9af 100644 --- a/app/models/enum/notification.go +++ b/app/models/enum/notification.go @@ -8,7 +8,7 @@ import ( type NotificationChannel int var ( - //NotificationChannelWeb is a in-app notification + //NotificationChannelWeb is an in-app notification NotificationChannelWeb NotificationChannel = 1 //NotificationChannelEmail is an email notification NotificationChannelEmail NotificationChannel = 2 diff --git a/app/models/enum/post_status.go b/app/models/enum/post_status.go index 58fb21ff9..b579d1067 100644 --- a/app/models/enum/post_status.go +++ b/app/models/enum/post_status.go @@ -10,9 +10,9 @@ var ( PostStarted PostStatus = 1 //PostCompleted is used when the post has been accepted and already implemented PostCompleted PostStatus = 2 - //PostDeclined is used when organizers decide to decline an post + //PostDeclined is used when organizers decide to decline a post PostDeclined PostStatus = 3 - //PostPlanned is used when organizers have accepted an post and it's on the roadmap + //PostPlanned is used when organizers have accepted a post and it's on the roadmap PostPlanned PostStatus = 4 //PostDuplicate is used when the post has already been posted before PostDuplicate PostStatus = 5 diff --git a/app/models/enum/webhook_status.go b/app/models/enum/webhook_status.go index 13857d4cd..1b69aa8e4 100644 --- a/app/models/enum/webhook_status.go +++ b/app/models/enum/webhook_status.go @@ -8,7 +8,7 @@ const ( WebhookEnabled WebhookStatus = 1 // WebhookDisabled means the webhook cannot be triggered WebhookDisabled WebhookStatus = 2 - // WebhookFailed means an error occured when the webhook was previously triggered and has been disabled + // WebhookFailed means an error occurred when the webhook was previously triggered and has been disabled WebhookFailed WebhookStatus = 3 ) diff --git a/app/models/query/email.go b/app/models/query/email.go index f393617d6..5a3e521f8 100644 --- a/app/models/query/email.go +++ b/app/models/query/email.go @@ -2,7 +2,7 @@ package query import "time" -type FetchRecentSupressions struct { +type FetchRecentSuppressions struct { StartTime time.Time //Output diff --git a/app/pkg/dbx/lock.go b/app/pkg/dbx/lock.go index 2a0f4d57e..332fbaba4 100644 --- a/app/pkg/dbx/lock.go +++ b/app/pkg/dbx/lock.go @@ -15,7 +15,7 @@ func hash(s string) uint32 { } // Try to obtain an advisory lock -// returns true and an unlock function if lock was aquired +// returns true and an unlock function if lock was acquired func TryLock(ctx context.Context, trx *Trx, key string) (bool, func()) { var locked bool if err := trx.Scalar(&locked, "SELECT pg_try_advisory_xact_lock($1)", hash(key)); err != nil { diff --git a/app/pkg/dbx/types.go b/app/pkg/dbx/types.go index 348a0e9d0..879355df2 100644 --- a/app/pkg/dbx/types.go +++ b/app/pkg/dbx/types.go @@ -5,7 +5,7 @@ import ( "encoding/json" ) -// NullInt representa a nullable integer +// NullInt represents a nullable integer type NullInt struct { sql.NullInt64 } @@ -18,7 +18,7 @@ func (r NullInt) MarshalJSON() ([]byte, error) { return json.Marshal(nil) } -// NullString representa a nullable string +// NullString represents a nullable string type NullString struct { sql.NullString } @@ -31,7 +31,7 @@ func (r NullString) MarshalJSON() ([]byte, error) { return json.Marshal(nil) } -// NullTime representa a nullable time.Time +// NullTime represents a nullable time.Time type NullTime struct { sql.NullTime } diff --git a/app/pkg/env/env.go b/app/pkg/env/env.go index fdf91b81c..c5c660d24 100644 --- a/app/pkg/env/env.go +++ b/app/pkg/env/env.go @@ -156,7 +156,7 @@ func init() { Reload() } -// Reload configuration from current Enviornment Variables +// Reload configuration from current Environment Variables func Reload() { Config = config{} err := envdecode.Decode(&Config) @@ -177,7 +177,7 @@ func Reload() { } } - // Email Type can be inferred if absense + // Email Type can be inferred if absent if Config.Email.Type == "" { if Config.Email.Mailgun.APIKey != "" { Config.Email.Type = "mailgun" diff --git a/app/pkg/errors/errors.go b/app/pkg/errors/errors.go index 672e367c1..27777d203 100644 --- a/app/pkg/errors/errors.go +++ b/app/pkg/errors/errors.go @@ -30,7 +30,7 @@ func Wrap(err error, format string, a ...any) error { return wrap(err, 0, format, a...) } -// Panicked wraps panick errow with extra details of error +// Panicked wraps panic error with extra details of error func Panicked(r any) error { err, ok := r.(error) if !ok { diff --git a/app/pkg/i18n/i18n.go b/app/pkg/i18n/i18n.go index f8264e566..9ecf00d96 100644 --- a/app/pkg/i18n/i18n.go +++ b/app/pkg/i18n/i18n.go @@ -69,7 +69,7 @@ func getLocaleData(locale string) localeData { } // getMessage returns the translated message for a given locale -// If given key is not found, it'll fallback to english +// If given key is not found, it'll fall back to English func getMessage(locale, key string) (string, *messageformat.Parser) { localeData := getLocaleData(locale) if str, ok := localeData.file[key]; ok && str != "" { @@ -100,17 +100,16 @@ func GetLocale(ctx context.Context) string { } func GetLocaleDirection(ctx context.Context) string { - locale := GetLocale(ctx) + locale := GetLocale(ctx) - localeInfo, found := enum.GetLocaleByCode(locale) - if found && localeInfo.IsRTL { - return "rtl" - } + localeInfo, found := enum.GetLocaleByCode(locale) + if found && localeInfo.IsRTL { + return "rtl" + } - return "ltr" + return "ltr" } - // T translates a given key to current locale // Params is used to replace variables and pluralize func T(ctx context.Context, key string, params ...Params) string { diff --git a/app/pkg/jsonq/jsonq.go b/app/pkg/jsonq/jsonq.go index 7dfc36b04..b97489da4 100644 --- a/app/pkg/jsonq/jsonq.go +++ b/app/pkg/jsonq/jsonq.go @@ -49,7 +49,7 @@ func (q *Query) String(selector string) string { return "" } -//Int32 returns a integer value from the json object based on its selector +//Int32 returns an integer value from the json object based on its selector func (q *Query) Int32(selector string) int { data := q.get(selector) if data != nil { diff --git a/app/pkg/validate/upload.go b/app/pkg/validate/upload.go index 8f392d73d..43c195b6f 100644 --- a/app/pkg/validate/upload.go +++ b/app/pkg/validate/upload.go @@ -11,7 +11,7 @@ import ( // MaxDimensionSize is the max width/height of an image. If image is bigger than this, it'll be resized. const MaxDimensionSize = 1500 -// MultiImageUploadOpts arguments to validate mulitple image upload process +// MultiImageUploadOpts arguments to validate multiple image upload process type MultiImageUploadOpts struct { MaxUploads int IsRequired bool @@ -30,7 +30,7 @@ type ImageUploadOpts struct { MaxKilobytes int } -//MultiImageUpload validates multiple image uploads +// MultiImageUpload validates multiple image uploads func MultiImageUpload(ctx context.Context, currentAttachments []string, uploads []*dto.ImageUpload, opts MultiImageUploadOpts) ([]string, error) { if currentAttachments == nil { currentAttachments = []string{} @@ -71,7 +71,7 @@ func MultiImageUpload(ctx context.Context, currentAttachments []string, uploads return []string{}, nil } -//ImageUpload validates given image upload +// ImageUpload validates given image upload func ImageUpload(ctx context.Context, upload *dto.ImageUpload, opts ImageUploadOpts) ([]string, error) { messages := []string{} diff --git a/app/pkg/web/ssl.go b/app/pkg/web/ssl.go index 59083aa28..f01bfe30b 100644 --- a/app/pkg/web/ssl.go +++ b/app/pkg/web/ssl.go @@ -124,7 +124,7 @@ func NewCertificateManager(ctx context.Context, certFile, keyFile string) (*Cert // GetCertificate decides which certificate to use // It first tries to use loaded certificate for incoming request if it's compatible -// Otherwise fallsback to a automatically generated certificate by Let's Encrypt +// Otherwise falls back to automatically generated certificate by Let's Encrypt func (m *CertificateManager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Certificate, error) { if m.leaf != nil { serverName, err := idna.Lookup.ToASCII(hello.ServerName) @@ -133,7 +133,7 @@ func (m *CertificateManager) GetCertificate(hello *tls.ClientHelloInfo) (*tls.Ce } serverName = strings.Trim(serverName, ".") - // If ServerName is empty or does't contain a dot, just return the certificate + // If ServerName is empty or doesn't contain a dot, just return the certificate if serverName == "" || !strings.Contains(serverName, ".") { return &m.cert, nil } diff --git a/app/pkg/web/util/webutil.go b/app/pkg/web/util/webutil.go index e1dff7611..12e61097c 100644 --- a/app/pkg/web/util/webutil.go +++ b/app/pkg/web/util/webutil.go @@ -54,7 +54,7 @@ func SetSignUpAuthCookie(ctx *web.Context, user *entity.User) { }) } -//GetSignUpAuthCookie returns the temporary temporary domain-wide Auth Token and removes it +//GetSignUpAuthCookie returns the temporary domain-wide Auth Token and removes it func GetSignUpAuthCookie(ctx *web.Context) string { cookie, err := ctx.Request.Cookie(web.CookieSignUpAuthName) if err == nil { diff --git a/app/services/blob/blob_test.go b/app/services/blob/blob_test.go index 3c3b841bb..8e2d0e60d 100644 --- a/app/services/blob/blob_test.go +++ b/app/services/blob/blob_test.go @@ -63,7 +63,7 @@ var tests = []struct { test blobTestCase }{ {"AllOperations", AllOperations}, - {"DeleteUnkownFile", DeleteUnkownFile}, + {"DeleteUnknownFile", DeleteUnknownFile}, {"KeyFormats", KeyFormats}, {"PathTraversalOnRead", PathTraversalOnRead}, {"SameKey_DifferentTenant", SameKey_DifferentTenant}, @@ -135,7 +135,7 @@ func AllOperations(ctx context.Context) { } } -func DeleteUnkownFile(ctx context.Context) { +func DeleteUnknownFile(ctx context.Context) { err := bus.Dispatch(ctx, &cmd.DeleteBlob{ Key: "path/somefile.txt", }) diff --git a/app/services/email/awsses/awsses.go b/app/services/email/awsses/awsses.go index 6339aed92..6da465319 100644 --- a/app/services/email/awsses/awsses.go +++ b/app/services/email/awsses/awsses.go @@ -52,7 +52,7 @@ func (s Service) Init() { sesClient = ses.New(awsSession) bus.AddListener(sendMail) - bus.AddHandler(fetchRecentSupressions) + bus.AddHandler(fetchRecentSuppressions) } func sendMail(ctx context.Context, c *cmd.SendMail) { @@ -128,13 +128,13 @@ func sendMail(ctx context.Context, c *cmd.SendMail) { } } -func fetchRecentSupressions(ctx context.Context, q *query.FetchRecentSupressions) error { +func fetchRecentSuppressions(ctx context.Context, q *query.FetchRecentSuppressions) error { response, err := sesClient.ListSuppressedDestinationsWithContext(ctx, &ses.ListSuppressedDestinationsInput{ StartDate: aws.Time(q.StartTime), PageSize: aws.Int64(1000), }) if err != nil { - return errors.Wrap(err, "failed to list supressed destinations") + return errors.Wrap(err, "failed to list suppressed destinations") } q.EmailAddresses = make([]string, 0) diff --git a/app/services/email/emailmock/emailmock.go b/app/services/email/emailmock/emailmock.go index 0594f460c..2a4960a6c 100644 --- a/app/services/email/emailmock/emailmock.go +++ b/app/services/email/emailmock/emailmock.go @@ -43,10 +43,10 @@ func (s Service) Enabled() bool { func (s Service) Init() { MessageHistory = make([]*HistoryItem, 0) bus.AddListener(sendMail) - bus.AddHandler(fetchRecentSupressions) + bus.AddHandler(fetchRecentSuppressions) } -func fetchRecentSupressions(ctx context.Context, c *query.FetchRecentSupressions) error { +func fetchRecentSuppressions(ctx context.Context, c *query.FetchRecentSuppressions) error { // not implemented for Email Mock return nil } diff --git a/app/services/email/mailgun/service.go b/app/services/email/mailgun/service.go index 0f9f8d804..38dc172f8 100644 --- a/app/services/email/mailgun/service.go +++ b/app/services/email/mailgun/service.go @@ -13,7 +13,7 @@ import ( // Known base URLs // Should Mailgun add other regions we'll just need to add their URLs here -// Use upper case keys - incoming env var values are normalized before being used +// Use uppercase keys - incoming env var values are normalized before being used var baseURLs = map[string]string{ "US": "https://api.mailgun.net/v3/%s", "EU": "https://api.eu.mailgun.net/v3/%s", @@ -39,7 +39,7 @@ func (s Service) Enabled() bool { func (s Service) Init() { bus.AddListener(sendMail) - bus.AddHandler(fetchRecentSupressions) + bus.AddHandler(fetchRecentSuppressions) } // Try getting the URL of the Mailgun API using Environment vars and the Sender's domain diff --git a/app/services/email/mailgun/supression.go b/app/services/email/mailgun/supression.go index 131771e47..ebb624814 100644 --- a/app/services/email/mailgun/supression.go +++ b/app/services/email/mailgun/supression.go @@ -26,8 +26,8 @@ type EventsResponse struct { } `json:"paging"` } -func fetchRecentSupressions(ctx context.Context, q *query.FetchRecentSupressions) error { - supressedAddresses := make(map[string]bool) +func fetchRecentSuppressions(ctx context.Context, q *query.FetchRecentSuppressions) error { + suppressedAddresses := make(map[string]bool) params := url.Values{} params.Set("event", "failed") @@ -43,13 +43,13 @@ func fetchRecentSupressions(ctx context.Context, q *query.FetchRecentSupressions } for _, item := range res.Items { - supressedAddresses[strings.TrimSpace(item.Recipient)] = true + suppressedAddresses[strings.TrimSpace(item.Recipient)] = true } // No more emails to fetch if len(res.Items) == 0 { q.EmailAddresses = make([]string, 0) - for email := range supressedAddresses { + for email := range suppressedAddresses { q.EmailAddresses = append(q.EmailAddresses, email) } return nil diff --git a/app/services/email/smtp/smtp.go b/app/services/email/smtp/smtp.go index a5b8f30a7..7e00dcce3 100644 --- a/app/services/email/smtp/smtp.go +++ b/app/services/email/smtp/smtp.go @@ -43,10 +43,10 @@ func (s Service) Enabled() bool { func (s Service) Init() { bus.AddListener(sendMail) - bus.AddHandler(fetchRecentSupressions) + bus.AddHandler(fetchRecentSuppressions) } -func fetchRecentSupressions(ctx context.Context, c *query.FetchRecentSupressions) error { +func fetchRecentSuppressions(ctx context.Context, c *query.FetchRecentSuppressions) error { //not implemented for SMTP return nil } diff --git a/app/services/oauth/oauth_test.go b/app/services/oauth/oauth_test.go index 16b018846..0509d7058 100644 --- a/app/services/oauth/oauth_test.go +++ b/app/services/oauth/oauth_test.go @@ -539,7 +539,7 @@ func TestParseOAuthRawProfile_CompositeName(t *testing.T) { expectedID: "123", }, { - name: "Composite path with missing field", + name: "Composite path missing a field", jsonBody: `{"id": "123", "firstname": "Jon", "email": "jon.snow@got.com"}`, jsonNamePath: "firstname + ' ' + lastname", expectedName: "Jon", // lastname is missing, so only firstname is used diff --git a/app/services/sqlstore/postgres/notification.go b/app/services/sqlstore/postgres/notification.go index af80a7e5c..25f53f887 100644 --- a/app/services/sqlstore/postgres/notification.go +++ b/app/services/sqlstore/postgres/notification.go @@ -182,10 +182,10 @@ func getActiveSubscribers(ctx context.Context, q *query.GetActiveSubscribers) er err error ) - // When searching for email subscrivers, skip users with email supressed - supressionCondition := "" + // When searching for email subscribers, skip users with email supressed + suppressionCondition := "" if q.Channel == enum.NotificationChannelEmail { - supressionCondition = "AND u.email_supressed_at IS NULL" + suppressionCondition = "AND u.email_supressed_at IS NULL" } // If the event doesn't require a subscription, notify everyone @@ -204,7 +204,7 @@ func getActiveSubscribers(ctx context.Context, q *query.GetActiveSubscribers) er (set.value IS NULL AND u.role = ANY($3)) OR CAST(set.value AS integer) & $4 > 0 ) - ORDER by u.id`, supressionCondition), + ORDER by u.id`, suppressionCondition), q.Event.UserSettingsKeyName, tenant.ID, pq.Array(q.Event.DefaultEnabledUserRoles), @@ -232,7 +232,7 @@ func getActiveSubscribers(ctx context.Context, q *query.GetActiveSubscribers) er (set.value IS NULL AND u.role = ANY($5)) OR CAST(set.value AS integer) & $6 > 0 ) - ORDER by u.id`, supressionCondition), + ORDER by u.id`, suppressionCondition), q.Number, enum.SubscriberActive, q.Event.UserSettingsKeyName, @@ -273,14 +273,14 @@ func internalAddSubscriber(trx *dbx.Trx, post *entity.Post, tenant *entity.Tenan return nil } -func supressEmail(ctx context.Context, c *cmd.SupressEmail) error { +func suppressEmail(ctx context.Context, c *cmd.SuppressEmail) error { return using(ctx, func(trx *dbx.Trx, tenant *entity.Tenant, user *entity.User) error { cmd := "UPDATE users SET email_supressed_at = $1 WHERE email = ANY($2) AND email_supressed_at IS NULL" rowsCount, err := trx.Execute(cmd, time.Now(), pq.Array(c.EmailAddresses)) if err != nil { - return errors.Wrap(err, "failed to update supress email: %s", strings.Join(c.EmailAddresses, ",")) + return errors.Wrap(err, "failed to update suppress email: %s", strings.Join(c.EmailAddresses, ",")) } - c.NumOfSupressedEmailAddresses = int(rowsCount) + c.NumOfSuppressedEmailAddresses = int(rowsCount) return nil }) } diff --git a/app/services/sqlstore/postgres/post.go b/app/services/sqlstore/postgres/post.go index 887536026..25bcf8b3b 100644 --- a/app/services/sqlstore/postgres/post.go +++ b/app/services/sqlstore/postgres/post.go @@ -140,7 +140,7 @@ func postIsReferenced(ctx context.Context, q *query.PostIsReferenced) error { func setPostResponse(ctx context.Context, c *cmd.SetPostResponse) error { return using(ctx, func(trx *dbx.Trx, tenant *entity.Tenant, user *entity.User) error { if c.Status == enum.PostDuplicate { - return errors.New("Use MarkAsDuplicate to change an post status to Duplicate") + return errors.New("Use MarkAsDuplicate to change a post status to Duplicate") } respondedAt := time.Now() diff --git a/app/services/sqlstore/postgres/postgres.go b/app/services/sqlstore/postgres/postgres.go index 2d825ea60..53cf08151 100644 --- a/app/services/sqlstore/postgres/postgres.go +++ b/app/services/sqlstore/postgres/postgres.go @@ -41,7 +41,7 @@ func (s Service) Init() { bus.AddHandler(addNewNotification) bus.AddHandler(addSubscriber) bus.AddHandler(removeSubscriber) - bus.AddHandler(supressEmail) + bus.AddHandler(suppressEmail) bus.AddHandler(getActiveSubscribers) bus.AddHandler(getTagBySlug) diff --git a/app/services/sqlstore/postgres/subscription_test.go b/app/services/sqlstore/postgres/subscription_test.go index 632281596..8194fc074 100644 --- a/app/services/sqlstore/postgres/subscription_test.go +++ b/app/services/sqlstore/postgres/subscription_test.go @@ -316,7 +316,7 @@ func TestSubscription_SubscribedToDifferentPost(t *testing.T) { Expect(q.Result[0].ID).Equals(jonSnow.ID) } -func TestSubscription_EmailSupressed(t *testing.T) { +func TestSubscription_EmailSuppressed(t *testing.T) { SetupDatabaseTest(t) defer TeardownDatabaseTest() @@ -342,8 +342,8 @@ func TestSubscription_EmailSupressed(t *testing.T) { Expect(q.Result[0].ID).Equals(jonSnow.ID) Expect(q.Result[1].ID).Equals(aryaStark.ID) - //Supress the email and verify that AryaStark is not an active subscriber anymore - err = bus.Dispatch(aryaStarkCtx, &cmd.SupressEmail{EmailAddresses: []string{aryaStark.Email}}) + //Suppress the email and verify that AryaStark is not an active subscriber anymore + err = bus.Dispatch(aryaStarkCtx, &cmd.SuppressEmail{EmailAddresses: []string{aryaStark.Email}}) Expect(err).IsNil() q = &query.GetActiveSubscribers{Number: newPost1.Result.Number, Channel: enum.NotificationChannelEmail, Event: enum.NotificationEventNewComment} diff --git a/app/tasks/new_comment.go b/app/tasks/new_comment.go index e26afc0c7..05aa35648 100644 --- a/app/tasks/new_comment.go +++ b/app/tasks/new_comment.go @@ -105,7 +105,7 @@ func NotifyAboutNewComment(comment *entity.Comment, post *entity.Post) worker.Ta } - // Standard email notitifications + // Standard email notifications users, err = getActiveSubscribers(c, post, enum.NotificationChannelEmail, enum.NotificationEventNewComment) if err != nil { return c.Failure(err) @@ -288,14 +288,14 @@ func sendEmailNotifications(c *worker.Context, post *entity.Post, to []dto.Recip author := c.User() tenant := c.Tenant() baseURL, logoURL := web.BaseURL(c), web.LogoURL(c) - messaleLocaleString := "email.new_comment.text" + messageLocaleString := "email.new_comment.text" if event.UserSettingsKeyName == enum.NotificationEventMention.UserSettingsKeyName { - messaleLocaleString = "email.new_mention.text" + messageLocaleString = "email.new_mention.text" } mailProps := dto.Props{ "title": post.Title, - "messageLocaleString": messaleLocaleString, + "messageLocaleString": messageLocaleString, "siteName": tenant.Name, "userName": author.Name, "content": markdown.Full(comment, false), diff --git a/locale/en/client.json b/locale/en/client.json index 5a77ed622..4a8f01192 100644 --- a/locale/en/client.json +++ b/locale/en/client.json @@ -224,7 +224,7 @@ "signin.code.sent": "A new code has been sent to your email.", "signin.email.placeholder": "Email address", "signin.message.email": "Continue with Email", - "signin.message.emaildisabled": "Email authentication has been disabled by an administrator. If you have an administrator account and need to bypass this restriction, please <0>click here.", + "signin.message.emaildisabled": "Email authentication has been disabled by an administrator. If you have an administrator account and need to, you can <0>bypass this restriction.", "signin.message.emailsent": "We have just sent a confirmation link to <0>{email}. Click the link and you’ll be signed in.", "signin.message.locked.text": "To reactivate this site, sign in with an administrator account and update the required settings.", "signin.message.locked.title": "<0>{0} is currently locked.", diff --git a/migrations/202510211300_add_search_column_to_posts.sql b/migrations/202510211300_add_search_column_to_posts.sql index 40356bad1..9af2def88 100644 --- a/migrations/202510211300_add_search_column_to_posts.sql +++ b/migrations/202510211300_add_search_column_to_posts.sql @@ -7,25 +7,25 @@ RETURNS regconfig AS $$ BEGIN RETURN CASE lang WHEN 'ar' THEN 'arabic'::regconfig - WHEN 'cs' THEN 'simple'::regconfig -- Czech not supported, fallback to simple + WHEN 'cs' THEN 'simple'::regconfig -- Czech not supported, fall back to simple WHEN 'de' THEN 'german'::regconfig - WHEN 'el' THEN 'simple'::regconfig -- Greek not supported, fallback to simple + WHEN 'el' THEN 'simple'::regconfig -- Greek not supported, fall back to simple WHEN 'en' THEN 'english'::regconfig WHEN 'es-ES' THEN 'spanish'::regconfig - WHEN 'fa' THEN 'simple'::regconfig -- Farsi not supported, fallback to simple + WHEN 'fa' THEN 'simple'::regconfig -- Farsi not supported, fall back to simple WHEN 'fr' THEN 'french'::regconfig WHEN 'it' THEN 'italian'::regconfig - WHEN 'ja' THEN 'simple'::regconfig -- Japanese not supported, fallback to simple - WHEN 'ko' THEN 'simple'::regconfig -- Korean not supported, fallback to simple + WHEN 'ja' THEN 'simple'::regconfig -- Japanese not supported, fall back to simple + WHEN 'ko' THEN 'simple'::regconfig -- Korean not supported, fall back to simple WHEN 'nl' THEN 'dutch'::regconfig - WHEN 'pl' THEN 'simple'::regconfig -- Polish not supported, fallback to simple + WHEN 'pl' THEN 'simple'::regconfig -- Polish not supported, fall back to simple WHEN 'pt-BR' THEN 'portuguese'::regconfig WHEN 'ru' THEN 'russian'::regconfig - WHEN 'sk' THEN 'simple'::regconfig -- Slovak not supported, fallback to simple - WHEN 'si-LK' THEN 'simple'::regconfig -- Sinhala not supported, fallback to simple + WHEN 'sk' THEN 'simple'::regconfig -- Slovak not supported, fall back to simple + WHEN 'si-LK' THEN 'simple'::regconfig -- Sinhala not supported, fall back to simple WHEN 'sv-SE' THEN 'swedish'::regconfig WHEN 'tr' THEN 'turkish'::regconfig - WHEN 'zh-CN' THEN 'simple'::regconfig -- Chinese not supported, fallback to simple + WHEN 'zh-CN' THEN 'simple'::regconfig -- Chinese not supported, fall back to simple ELSE 'simple'::regconfig END; END; diff --git a/public/components/PostDetails/PostDetails.tsx b/public/components/PostDetails/PostDetails.tsx index 4a7a5c43b..22fd5186a 100644 --- a/public/components/PostDetails/PostDetails.tsx +++ b/public/components/PostDetails/PostDetails.tsx @@ -66,7 +66,7 @@ const PostMetaInfo = ({ post, locale }: { post: Post; locale: string }) => ( ) export const PostDetails: React.FC = (props) => { - // If we have initial data, use it; otherwise we'll fetch + // If we have initial data, use it; otherwise, we'll fetch const [post, setPost] = useState(props.initialPost || null) const [subscribed, setSubscribed] = useState(props.initialSubscribed || false) const [comments, setComments] = useState(props.initialComments || []) diff --git a/public/components/common/form/CustomImage.ts b/public/components/common/form/CustomImage.ts index 99916f0b5..898d764c1 100644 --- a/public/components/common/form/CustomImage.ts +++ b/public/components/common/form/CustomImage.ts @@ -66,7 +66,7 @@ export const CustomImage = Image.extend({ } // When serializing to markdown, we use a special syntax: ![](fider-image:bkey) - // Use bkey if available, otherwise fall back to id + // Use bkey if available; otherwise, fall back to id const imageId = node.attrs.bkey || node.attrs.id || "" state.write(`![](fider-image:${imageId})`) }, diff --git a/public/hooks/use-script.ts b/public/hooks/use-script.ts index d49cb85e2..b266e6d1a 100644 --- a/public/hooks/use-script.ts +++ b/public/hooks/use-script.ts @@ -16,7 +16,7 @@ export function useScript(src: string) { } // Fetch existing script element by src - // It may have been added by another intance of this hook + // It may have been added by another instance of this hook let script: HTMLScriptElement | null = document.querySelector(`script[src="${src}"]`) if (!script) { // Create script diff --git a/public/hooks/useAttachments.ts b/public/hooks/useAttachments.ts index 9ae7e7930..06a4598e2 100644 --- a/public/hooks/useAttachments.ts +++ b/public/hooks/useAttachments.ts @@ -48,7 +48,7 @@ export const useAttachments = (options: UseAttachmentsOptions = {}): UseAttachme // 1.If the bkey exists in attachments: // 1.1 If there is something in upload.content, then it's a new upload that's not yet saved, so just remove the entry from attachments. // 1.2 If there is nothing in upload.content, it's been previously uploaded, so set the remove flag to true. - // 2. If the bkey doesn't exist, then you're editing, and attachments hasn't been "primed" so add it as a new one but with with remove flag set to true + // 2. If the bkey doesn't exist, then you're editing, and attachments hasn't been "primed" so add it as a new one but with the remove flag set to true const existing = prev.find((att) => att.bkey === upload.bkey) diff --git a/public/pages/Administration/components/webhook/WebhookTemplateInfoModal.tsx b/public/pages/Administration/components/webhook/WebhookTemplateInfoModal.tsx index cee3ac265..b85e1257d 100644 --- a/public/pages/Administration/components/webhook/WebhookTemplateInfoModal.tsx +++ b/public/pages/Administration/components/webhook/WebhookTemplateInfoModal.tsx @@ -65,13 +65,13 @@ const functions: StringObject = { }, quote: { params: [{ type: "string", desc: "The input string to quote" }], - description: "Enquote a string and escape inner special characters", + description: "Quote a string and escape inner special characters", info: "You should use this function when using a value as a JSON field", }, escape: { params: [{ type: "string", desc: "The input string to escape" }], - description: "Escape inner special characters of a string, without enquoting it", - info: "You should use this function when using a value within an enquoted string", + description: "Escape inner special characters of a string, without quoting it", + info: "You should use this function when using a value within a quoted string", }, urlquery: { params: [{ type: "string", desc: "The input string to encode as URL query value" }], @@ -114,8 +114,8 @@ export const WebhookTemplateInfoModal = (props: WebhookTemplateInfoProps) => {

What is a template?

- The template engine used is the native Go text/template package. The simpliest way to create a template is to write your text, and - insert the property name, prefixed by a dot, enclosed in double braces with spaces within (wierd? complete!). Example: + The template engine used is the native Go text/template package. The simplest way to create a template is to write your text, and + insert the property name, prefixed by a dot, enclosed in double braces with spaces within (weird? complete!). Example:

{textExample}

diff --git a/public/pages/Administration/pages/Invitations.page.tsx b/public/pages/Administration/pages/Invitations.page.tsx index a6d19fcd1..5a8ac7f01 100644 --- a/public/pages/Administration/pages/Invitations.page.tsx +++ b/public/pages/Administration/pages/Invitations.page.tsx @@ -102,7 +102,7 @@ ${Fider.session.user.name} (${Fider.session.tenant.name})`,