Compare commits

...

11 Commits
0.8.0 ... main

Author SHA1 Message Date
Jan Dittberner 39393eb612 Adapt goreleaser config for gorelease v2.0.0
cacert-boardvoting/pipeline/head This commit looks good Details
3 weeks ago
Jan Dittberner a8f16192a8 Update dependencies 3 weeks ago
Jan Dittberner 11582d3590 Update linter config and apply suggestions
- remove copyright years (they are in git)
- remove outdated linter bug workarounds
- update .golangci.yml to match current schema (as of golangci-lint 1.59.0)
3 weeks ago
Jan Dittberner 3d16034c44 Add configurable domain part for message ids
Fixes #1
3 weeks ago
Jan Dittberner 20d324f5cb Fix linter error
cacert-boardvoting/pipeline/head This commit looks good Details
- remove nextPotentialRun.Add that had no effect
1 year ago
Jan Dittberner 4276594f8d Bump copyright year
cacert-boardvoting/pipeline/head There was a failure building this commit Details
1 year ago
Jan Dittberner 4a8307e16a Fix display of user 1 year ago
Jan Dittberner 12796486d2 Fix summarizing vote results 1 year ago
Jan Dittberner f27f2bf801 Update to go 1.19
- update go tool in Jenkinsfile
- update go version in go.mod
- update README.md
- update dependencies
1 year ago
Jan Dittberner d0052ff3dc Import go-sqlite3 to fix test
cacert-boardvoting/pipeline/head This commit looks good Details
2 years ago
Jan Dittberner c9d3f2a20a Fix permission issues for unauthenticated users
cacert-boardvoting/pipeline/head This commit looks good Details
2 years ago

@ -1,7 +1,9 @@
--- ---
run: run:
go: "1.17" go: "1.22"
skip-files:
issues:
exclude-files:
- boardvoting/assets.go - boardvoting/assets.go
output: output:
@ -13,7 +15,7 @@ linters-settings:
const: const:
ORGANIZATION: CAcert Inc. ORGANIZATION: CAcert Inc.
template: |- template: |-
Copyright {{ YEAR-RANGE }} {{ ORGANIZATION }} Copyright {{ ORGANIZATION }}
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -27,8 +29,8 @@ linters-settings:
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
gomnd: mnd:
ignore-functions: ignored-functions:
- 'strconv.*' - 'strconv.*'
ignored-numbers: ignored-numbers:
- '-1,0,1,2,8' - '-1,0,1,2,8'
@ -57,7 +59,7 @@ linters:
- gofmt - gofmt
- goheader - goheader
- goimports - goimports
- gomnd - mnd
- gosec - gosec
- lll - lll
- makezero - makezero

@ -1,6 +1,7 @@
# This is an example .goreleaser.yml file with some sane defaults. # This is an example .goreleaser.yml file with some sane defaults.
# Make sure to check the documentation at http://goreleaser.com # Make sure to check the documentation at http://goreleaser.com
project_name: cacert-boardvoting project_name: cacert-boardvoting
version: 2
before: before:
hooks: hooks:
- go mod tidy - go mod tidy
@ -17,11 +18,6 @@ builds:
- -trimpath - -trimpath
- -v - -v
main: ./cmd/boardvoting main: ./cmd/boardvoting
archives:
- replacements:
linux: Linux
amd64: x86_64
format: binary
checksum: checksum:
name_template: 'checksums.txt' name_template: 'checksums.txt'
snapshot: snapshot:

4
Jenkinsfile vendored

@ -1,6 +1,6 @@
#!groovy #!groovy
/* /*
Copyright 2017-2022 Jan Dittberner Copyright 2017-2023 Jan Dittberner
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this program except in compliance with the License. you may not use this program except in compliance with the License.
@ -18,7 +18,7 @@ pipeline {
agent any agent any
tools { tools {
go "go-1.18" go "go-1.19"
} }
environment { environment {

@ -53,7 +53,7 @@ Last Changed Date: 2009-07-12 04:02:38 +0000 (Sun, 12 Jul 2009)
Local development requires Local development requires
* golang >= 1.18 * golang >= 1.19
* sqlite3 and development headers * sqlite3 and development headers
* GNU make * GNU make
* nodejs, npm and gulp (only needed if you intend to update the [jQuery] or [Fomantic-UI] CSS and JavaScript) * nodejs, npm and gulp (only needed if you intend to update the [jQuery] or [Fomantic-UI] CSS and JavaScript)

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -7,6 +7,7 @@ mail_config:
smtp_host: localhost smtp_host: localhost
smtp_port: 25 smtp_port: 25
base_url: https://motions.cacert.org base_url: https://motions.cacert.org
domain: motions.cacert.org
notice_mail_address: cacert-board@lists.cacert.org notice_mail_address: cacert-board@lists.cacert.org
vote_notice_mail_address: cacert-board-votes@lists.cacert.org vote_notice_mail_address: cacert-board-votes@lists.cacert.org
notification_sender_address: returns@cacert.org notification_sender_address: returns@cacert.org

@ -1,46 +1,46 @@
module git.cacert.org/cacert-boardvoting module git.cacert.org/cacert-boardvoting
go 1.18 go 1.22
require ( require (
github.com/Masterminds/sprig/v3 v3.2.2 github.com/Masterminds/sprig/v3 v3.2.3
github.com/golang-migrate/migrate/v4 v4.15.2 github.com/golang-migrate/migrate/v4 v4.17.1
github.com/google/uuid v1.3.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/huandu/xstrings v1.3.2 // indirect github.com/huandu/xstrings v1.5.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect github.com/imdario/mergo v0.3.16 // indirect
github.com/jmoiron/sqlx v1.3.5 github.com/jmoiron/sqlx v1.4.0
github.com/johejo/golang-migrate-extra v0.0.0-20211005021153-c17dd75f8b4a github.com/johejo/golang-migrate-extra v0.0.0-20211005021153-c17dd75f8b4a
github.com/mattn/go-sqlite3 v1.14.12 github.com/mattn/go-sqlite3 v1.14.22
github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/vearutop/statigz v1.1.8 github.com/vearutop/statigz v1.4.0
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 // indirect golang.org/x/crypto v0.24.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/mail.v2 v2.3.1 gopkg.in/mail.v2 v2.3.1
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )
require ( require (
github.com/alexedwards/scs/sqlite3store v0.0.0-20220216073957-c252878bcf5a github.com/alexedwards/scs/sqlite3store v0.0.0-20240316134038-7e11d57e8885
github.com/alexedwards/scs/v2 v2.5.0 github.com/alexedwards/scs/v2 v2.8.0
github.com/go-chi/chi/v5 v5.0.7 github.com/go-chi/chi/v5 v5.0.12
github.com/go-playground/form/v4 v4.2.0 github.com/go-playground/form/v4 v4.2.1
github.com/justinas/nosurf v1.1.1 github.com/justinas/nosurf v1.1.1
github.com/lestrrat-go/tcputil v0.0.0-20180223003554-d3c7f98154fb github.com/lestrrat-go/tcputil v0.0.0-20180223003554-d3c7f98154fb
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.8.3
golang.org/x/text v0.3.7 golang.org/x/text v0.16.0
) )
require ( require (
github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect github.com/andybalholm/brotli v1.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect github.com/shopspring/decimal v1.4.0 // indirect
github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cast v1.6.0 // indirect
go.uber.org/atomic v1.9.0 // indirect go.uber.org/atomic v1.11.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
) )

1364
go.sum

File diff suppressed because it is too large Load Diff

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -199,12 +199,10 @@ func (app *Application) Routes() http.Handler {
r.Get("/newmotion/", motionHandler.NewForm) r.Get("/newmotion/", motionHandler.NewForm)
r.Post("/newmotion/", motionHandler.New) r.Post("/newmotion/", motionHandler.New)
r.Route("/motions/{tag}", func(r chi.Router) { r.Get("/motions/{tag}/edit", motionHandler.EditForm)
r.Get("/edit", motionHandler.EditForm) r.Post("/motions/{tag}/edit", motionHandler.Edit)
r.Post("/edit", motionHandler.Edit) r.Get("/motions/{tag}/withdraw", motionHandler.WithdrawForm)
r.Get("/withdraw", motionHandler.WithdrawForm) r.Post("/motions/{tag}/withdraw", motionHandler.Withdraw)
r.Post("/withdraw", motionHandler.Withdraw)
})
}) })
r.Group(func(r chi.Router) { r.Group(func(r chi.Router) {

@ -1,5 +1,5 @@
/* /*
Copyright 2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -33,6 +33,8 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
_ "github.com/mattn/go-sqlite3"
"git.cacert.org/cacert-boardvoting/internal/notifications" "git.cacert.org/cacert-boardvoting/internal/notifications"
"git.cacert.org/cacert-boardvoting/internal/models" "git.cacert.org/cacert-boardvoting/internal/models"

@ -1,5 +1,5 @@
/* /*
Copyright 2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -62,7 +62,7 @@ func Test_secureHeaders(t *testing.T) {
SecureHeaders(next).ServeHTTP(rr, r) SecureHeaders(next).ServeHTTP(rr, r)
rs := rr.Result() //nolint:bodyclose // linters bug rs := rr.Result()
defer func() { _ = rs.Body.Close() }() defer func() { _ = rs.Body.Close() }()
@ -119,7 +119,7 @@ func TestApplication_tryAuthenticate(t *testing.T) {
mw.TryAuthenticate(next).ServeHTTP(rr, r) mw.TryAuthenticate(next).ServeHTTP(rr, r)
rs := rr.Result() //nolint:bodyclose // linters bug rs := rr.Result()
defer func() { _ = rs.Body.Close() }() defer func() { _ = rs.Body.Close() }()
@ -137,7 +137,7 @@ func TestApplication_tryAuthenticate(t *testing.T) {
mw.TryAuthenticate(next).ServeHTTP(rr, r) mw.TryAuthenticate(next).ServeHTTP(rr, r)
rs := rr.Result() //nolint:bodyclose // linters bug rs := rr.Result()
defer func() { _ = rs.Body.Close() }() defer func() { _ = rs.Body.Close() }()
@ -158,11 +158,12 @@ func TestApplication_tryAuthenticate(t *testing.T) {
mw.TryAuthenticate(next).ServeHTTP(rr, r) mw.TryAuthenticate(next).ServeHTTP(rr, r)
rs := rr.Result() //nolint:bodyclose // linters bug rs := rr.Result()
defer func() { _ = rs.Body.Close() }() defer func() { _ = rs.Body.Close() }()
assert.Equal(t, http.StatusOK, rs.StatusCode) assert.Equal(t, http.StatusOK, rs.StatusCode)
user := nextCtx.Value(ctxUser) user := nextCtx.Value(ctxUser)
assert.NotNil(t, user) assert.NotNil(t, user)

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -34,6 +34,10 @@ import (
) )
func checkRole(v *models.User, roles ...models.RoleName) (bool, error) { func checkRole(v *models.User, roles ...models.RoleName) (bool, error) {
if v == nil {
return false, nil
}
hasRole, err := v.HasRole(roles...) hasRole, err := v.HasRole(roles...)
if err != nil { if err != nil {
return false, fmt.Errorf("could not determine user roles: %w", err) return false, fmt.Errorf("could not determine user roles: %w", err)

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -47,7 +47,6 @@ func (r *RemindVotersJob) Schedule() {
year, month, day := now.Date() year, month, day := now.Date()
nextPotentialRun := time.Date(year, month, day+1, 0, 0, 0, 0, time.UTC) nextPotentialRun := time.Date(year, month, day+1, 0, 0, 0, 0, time.UTC)
nextPotentialRun.Add(hoursInDay * time.Hour)
relevantDue := nextPotentialRun.Add(reminderDays * hoursInDay * time.Hour) relevantDue := nextPotentialRun.Add(reminderDays * hoursInDay * time.Hour)

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -458,13 +458,15 @@ func sumsForDecision(ctx context.Context, tx *sqlx.Tx, d *Motion) (*VoteSums, er
return nil, fmt.Errorf("could not parse row for vote sums of motion %s: %w", d.Tag, err) return nil, fmt.Errorf("could not parse row for vote sums of motion %s: %w", d.Tag, err)
} }
switch vote { switch vote.ID {
case VoteAye: case VoteAye.ID:
sums.Ayes = count sums.Ayes = count
case VoteNaye: case VoteNaye.ID:
sums.Nayes = count sums.Nayes = count
case VoteAbstain: case VoteAbstain.ID:
sums.Abstains = count sums.Abstains = count
default:
return nil, fmt.Errorf("unknown vote type '%+v'", vote)
} }
} }
@ -605,12 +607,12 @@ func (m *MotionModel) List(ctx context.Context, options *MotionListOptions) ([]*
} }
func (m *MotionModel) FillVoteSums(ctx context.Context, decisions []*Motion) error { func (m *MotionModel) FillVoteSums(ctx context.Context, decisions []*Motion) error {
decisionIds := make([]int64, len(decisions)) decisionIDs := make([]int64, len(decisions))
decisionMap := make(map[int64]*Motion, len(decisions)) decisionMap := make(map[int64]*Motion, len(decisions))
for idx, decision := range decisions { for idx, decision := range decisions {
decision.Sums = &VoteSums{} decision.Sums = &VoteSums{}
decisionIds[idx] = decision.ID decisionIDs[idx] = decision.ID
decisionMap[decision.ID] = decision decisionMap[decision.ID] = decision
} }
@ -619,7 +621,7 @@ func (m *MotionModel) FillVoteSums(ctx context.Context, decisions []*Motion) err
FROM votes v FROM votes v
WHERE v.decision IN (?) WHERE v.decision IN (?)
GROUP BY v.decision, v.vote`, GROUP BY v.decision, v.vote`,
decisionIds, decisionIDs,
) )
if err != nil { if err != nil {
return fmt.Errorf("could not create IN query: %w", err) return fmt.Errorf("could not create IN query: %w", err)

@ -1,5 +1,5 @@
/* /*
Copyright 2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -251,6 +251,10 @@ WHERE e.address IN (?)`, emails)
} }
} }
if count == 0 {
return nil, nil
}
if user.roles, err = m.Roles(ctx, &user); err != nil { if user.roles, err = m.Roles(ctx, &user); err != nil {
return nil, fmt.Errorf("could not retrieve roles for user %s: %w", user.Name, err) return nil, fmt.Errorf("could not retrieve roles for user %s: %w", user.Name, err)
} }

@ -1,5 +1,5 @@
/* /*
Copyright 2017-2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
@ -38,6 +38,7 @@ type MailConfig struct {
SMTPHost string `yaml:"smtp_host"` SMTPHost string `yaml:"smtp_host"`
SMTPPort int `yaml:"smtp_port"` SMTPPort int `yaml:"smtp_port"`
SMTPTimeOut time.Duration `yaml:"smtp_timeout,omitempty"` SMTPTimeOut time.Duration `yaml:"smtp_timeout,omitempty"`
Domain string `yaml:"message_id_domain"`
NotificationSenderAddress string `yaml:"notification_sender_address"` NotificationSenderAddress string `yaml:"notification_sender_address"`
NoticeMailAddress string `yaml:"notice_mail_address"` NoticeMailAddress string `yaml:"notice_mail_address"`
VoteNoticeMailAddress string `yaml:"vote_notice_mail_address"` VoteNoticeMailAddress string `yaml:"vote_notice_mail_address"`
@ -202,10 +203,10 @@ func voteNoticeRecipient(mc *MailConfig) recipientData {
} }
} }
func motionReplyHeaders(m *models.Motion) map[string][]string { func motionReplyHeaders(m *models.Motion, mc *MailConfig) map[string][]string {
return map[string][]string{ return map[string][]string{
"References": {fmt.Sprintf("<%s>", m.Tag)}, "References": {fmt.Sprintf("<%s@%s>", m.Tag, mc.Domain)},
"In-Reply-To": {fmt.Sprintf("<%s>", m.Tag)}, "In-Reply-To": {fmt.Sprintf("<%s@%s>", m.Tag, mc.Domain)},
} }
} }
@ -247,7 +248,7 @@ func (c *ClosedDecisionNotification) GetNotificationContent(mc *MailConfig) *Not
*models.Motion *models.Motion
}{Motion: c.Decision}, }{Motion: c.Decision},
subject: fmt.Sprintf("Re: %s - %s - finalized", c.Decision.Tag, c.Decision.Title), subject: fmt.Sprintf("Re: %s - %s - finalized", c.Decision.Tag, c.Decision.Title),
headers: motionReplyHeaders(c.Decision), headers: motionReplyHeaders(c.Decision, mc),
recipients: []recipientData{defaultRecipient(mc)}, recipients: []recipientData{defaultRecipient(mc)},
} }
} }
@ -275,14 +276,14 @@ func (n NewDecisionNotification) GetNotificationContent(mc *MailConfig) *Notific
UnvotedURL: unvotedURL, UnvotedURL: unvotedURL,
}, },
subject: fmt.Sprintf("%s - %s", n.Decision.Tag, n.Decision.Title), subject: fmt.Sprintf("%s - %s", n.Decision.Tag, n.Decision.Title),
headers: n.getHeaders(), headers: n.getHeaders(mc),
recipients: []recipientData{defaultRecipient(mc)}, recipients: []recipientData{defaultRecipient(mc)},
} }
} }
func (n NewDecisionNotification) getHeaders() map[string][]string { func (n NewDecisionNotification) getHeaders(mc *MailConfig) map[string][]string {
return map[string][]string{ return map[string][]string{
"Message-ID": {fmt.Sprintf("<%s>", n.Decision.Tag)}, "Message-ID": {fmt.Sprintf("<%s@%s>", n.Decision.Tag, mc.Domain)},
} }
} }
@ -309,7 +310,7 @@ func (u UpdateDecisionNotification) GetNotificationContent(mc *MailConfig) *Noti
UnvotedURL: unvotedURL, UnvotedURL: unvotedURL,
}, },
subject: fmt.Sprintf("%s - %s", u.Decision.Tag, u.Decision.Title), subject: fmt.Sprintf("%s - %s", u.Decision.Tag, u.Decision.Title),
headers: motionReplyHeaders(u.Decision), headers: motionReplyHeaders(u.Decision, mc),
recipients: []recipientData{defaultRecipient(mc)}, recipients: []recipientData{defaultRecipient(mc)},
} }
} }
@ -333,7 +334,7 @@ func (d DirectVoteNotification) GetNotificationContent(mc *MailConfig) *Notifica
Choice: d.Choice, Choice: d.Choice,
}, },
subject: fmt.Sprintf("Re: %s - %s", d.Decision.Tag, d.Decision.Title), subject: fmt.Sprintf("Re: %s - %s", d.Decision.Tag, d.Decision.Title),
headers: motionReplyHeaders(d.Decision), headers: motionReplyHeaders(d.Decision, mc),
recipients: []recipientData{voteNoticeRecipient(mc)}, recipients: []recipientData{voteNoticeRecipient(mc)},
} }
} }
@ -363,7 +364,7 @@ func (p ProxyVoteNotification) GetNotificationContent(mc *MailConfig) *Notificat
Justification: p.Justification, Justification: p.Justification,
}, },
subject: fmt.Sprintf("Re: %s - %s", p.Decision.Tag, p.Decision.Title), subject: fmt.Sprintf("Re: %s - %s", p.Decision.Tag, p.Decision.Title),
headers: motionReplyHeaders(p.Decision), headers: motionReplyHeaders(p.Decision, mc),
recipients: []recipientData{voteNoticeRecipient(mc)}, recipients: []recipientData{voteNoticeRecipient(mc)},
} }
} }
@ -381,7 +382,7 @@ func (w WithDrawMotionNotification) GetNotificationContent(mc *MailConfig) *Noti
Name string Name string
}{Motion: w.Motion, Name: w.Voter.Name}, }{Motion: w.Motion, Name: w.Voter.Name},
subject: fmt.Sprintf("Re: %s - %s", w.Motion.Tag, w.Motion.Title), subject: fmt.Sprintf("Re: %s - %s", w.Motion.Tag, w.Motion.Title),
headers: motionReplyHeaders(w.Motion), headers: motionReplyHeaders(w.Motion, mc),
recipients: []recipientData{defaultRecipient(mc)}, recipients: []recipientData{defaultRecipient(mc)},
} }
} }

@ -1,5 +1,5 @@
/* /*
Copyright 2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -1,5 +1,5 @@
/* /*
Copyright 2022 CAcert Inc. Copyright CAcert Inc.
SPDX-License-Identifier: Apache-2.0 SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");

@ -19,7 +19,7 @@
{{ with .User }} {{ with .User }}
<div class="ui label"> <div class="ui label">
<i class="id card outline icon"></i> <i class="id card outline icon"></i>
Authenticated as {{ .Name }} &lt;{{ .Reminder }}&gt; Authenticated as {{ .Name }} &lt;{{ .Reminder.String }}&gt;
</div> </div>
{{ end }} {{ end }}
</div> </div>
@ -42,7 +42,7 @@
</main> </main>
<footer class="ui vertical footer segment"> <footer class="ui vertical footer segment">
<div class="ui container"> <div class="ui container">
<span class="ui small text">© 2017-2022 CAcert Inc.</span> <span class="ui small text">© 2017-2023 CAcert Inc.</span>
</div> </div>
</footer> </footer>
</body> </body>

Loading…
Cancel
Save