diff --git a/go.mod b/go.mod index 27ca3d7..8000486 100644 --- a/go.mod +++ b/go.mod @@ -7,15 +7,15 @@ toolchain go1.23.1 require ( github.com/archdx/zerolog-sentry v1.8.4 github.com/emersion/go-msgauth v0.6.8 - github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 + github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 github.com/emersion/go-smtp v0.21.3 github.com/etkecc/go-env v1.2.1 github.com/etkecc/go-fswatcher v1.0.1 - github.com/etkecc/go-healthchecks/v2 v2.2.1 - github.com/etkecc/go-linkpearl v0.0.0-20240916112808-1ff87355b2b3 + github.com/etkecc/go-healthchecks/v2 v2.2.2 + github.com/etkecc/go-linkpearl v0.0.0-20241016081935-715b568101ef github.com/etkecc/go-mxidwc v1.0.1 github.com/etkecc/go-psd v0.0.0-20241014083754-1bc4ec777ba8 - github.com/etkecc/go-secgen v1.3.0 + github.com/etkecc/go-secgen v1.4.0 github.com/etkecc/go-validator/v2 v2.2.4 github.com/fsnotify/fsnotify v1.7.0 github.com/gabriel-vasile/mimetype v1.4.6 @@ -29,7 +29,7 @@ require ( github.com/rs/zerolog v1.33.0 github.com/swaggo/swag v1.16.3 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c - maunium.net/go/mautrix v0.21.0 + maunium.net/go/mautrix v0.21.1 modernc.org/sqlite v1.33.1 ) @@ -59,7 +59,7 @@ require ( github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a // indirect github.com/ncruces/go-strftime v0.1.9 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 // indirect + github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rivo/uniseg v0.4.7 // indirect @@ -68,8 +68,8 @@ require ( github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect - github.com/yuin/goldmark v1.7.6 // indirect - go.mau.fi/util v0.8.0 // indirect + github.com/yuin/goldmark v1.7.8 // indirect + go.mau.fi/util v0.8.1 // indirect golang.org/x/crypto v0.28.0 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/sys v0.26.0 // indirect diff --git a/go.sum b/go.sum index faec2fe..e6765df 100644 --- a/go.sum +++ b/go.sum @@ -26,24 +26,24 @@ github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+m github.com/emersion/go-msgauth v0.6.8 h1:kW/0E9E8Zx5CdKsERC/WnAvnXvX7q9wTHia1OA4944A= github.com/emersion/go-msgauth v0.6.8/go.mod h1:YDwuyTCUHu9xxmAeVj0eW4INnwB6NNZoPdLerpSxRrc= github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= -github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 h1:hH4PQfOndHDlpzYfLAAfl63E8Le6F2+EL/cdhlkyRJY= -github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= +github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 h1:oP4q0fw+fOSWn3DfFi4EXdT+B+gTtzx8GC9xsc26Znk= +github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ= github.com/emersion/go-smtp v0.21.3 h1:7uVwagE8iPYE48WhNsng3RRpCUpFvNl39JGNSIyGVMY= github.com/emersion/go-smtp v0.21.3/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ= github.com/etkecc/go-env v1.2.1 h1:b/mIa8D1d9hc3rI8h5bEtBHsnKkBZ6UbmYPog3QIPTU= github.com/etkecc/go-env v1.2.1/go.mod h1:yTs1DWEsllAZYA417r4V+OmMuYinGXtBzKkLGNvCv5c= github.com/etkecc/go-fswatcher v1.0.1 h1:n9hqtjzTS3ETb9hcZe1EqYA1lkkhlzZlztu3hXwFDQc= github.com/etkecc/go-fswatcher v1.0.1/go.mod h1:O5TODJ9z6Qb7X+snqHbB+F0Pah6G497Wdg0SFE/UYpE= -github.com/etkecc/go-healthchecks/v2 v2.2.1 h1:veGW/EoFuF4mB9ylHhCB4C98MY2kjl3++wZ7g6KRSXg= -github.com/etkecc/go-healthchecks/v2 v2.2.1/go.mod h1:IowWGN4F6By6z0eh63+639OscylgtdvT9ITjfN6hnZA= -github.com/etkecc/go-linkpearl v0.0.0-20240916112808-1ff87355b2b3 h1:Mkf7lWP0lf5Hv8g4x+p1IJ64kfQYIX85z8dKDjsKeuw= -github.com/etkecc/go-linkpearl v0.0.0-20240916112808-1ff87355b2b3/go.mod h1:lmPUKcFUSGuJ2kwqL9Yc5gWsBKVGQr+smuDCX+BqMWY= +github.com/etkecc/go-healthchecks/v2 v2.2.2 h1:YV7e+Ga8JY3aZX4Qf6Q1Ca+DnqbT5Drjli3PufB4J1g= +github.com/etkecc/go-healthchecks/v2 v2.2.2/go.mod h1:IowWGN4F6By6z0eh63+639OscylgtdvT9ITjfN6hnZA= +github.com/etkecc/go-linkpearl v0.0.0-20241016081935-715b568101ef h1:c+7TLGW847a/7nOxNg8ICXBa8DB3WnnH9mAN9d2Ntuw= +github.com/etkecc/go-linkpearl v0.0.0-20241016081935-715b568101ef/go.mod h1:VEzhQeweZez8RKYSEYQhULddGeaNsaVcuWzlb1k8EFM= github.com/etkecc/go-mxidwc v1.0.1 h1:t4Kq3FxSlQjt1i7RpzE5q3cOWjJ0vrTzzGZRSpgh8mg= github.com/etkecc/go-mxidwc v1.0.1/go.mod h1:WFlntcH4mdual/gNi6X7a6rSJERNuLjdrwM3K/tucQA= github.com/etkecc/go-psd v0.0.0-20241014083754-1bc4ec777ba8 h1:ariQTBlHHe71O507IZ97QSHFrk0Eo2vlMm1skJ97Y7Q= github.com/etkecc/go-psd v0.0.0-20241014083754-1bc4ec777ba8/go.mod h1:x4ORuml+JdRsska0sXHbpSQAqvQyqDLjXydP5Ax5wBg= -github.com/etkecc/go-secgen v1.3.0 h1:DfytmSQL7W0nL7E0kmgDCrorU7V3e2bT5XBgrIisbbs= -github.com/etkecc/go-secgen v1.3.0/go.mod h1:6dkfdOtmtVxkj1hIJM6U6yA7frSNpr1H5brz5t18Y3I= +github.com/etkecc/go-secgen v1.4.0 h1:PapLpen3aIqG2LDu+U6KWDb4SMW2UGuvetpJjd86yUc= +github.com/etkecc/go-secgen v1.4.0/go.mod h1:6dkfdOtmtVxkj1hIJM6U6yA7frSNpr1H5brz5t18Y3I= github.com/etkecc/go-trysmtp v1.1.5 h1:MQ4l4bE9nWUqRKoJOalGHGLkb/hRmzbcBMlClufEOng= github.com/etkecc/go-trysmtp v1.1.5/go.mod h1:J4zQu+kgM37xQY148wUz0Dm6y+YhtzMghAv/AaXt0sQ= github.com/etkecc/go-validator/v2 v2.2.4 h1:E4sE4FpYPVP6VRvnndni+8qUXbeSuHxkniFsi6uCRFQ= @@ -108,8 +108,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/mattn/go-sqlite3 v1.14.23 h1:gbShiuAP1W5j9UOksQ06aiiqPMxYecovVGwmTxWtuw0= -github.com/mattn/go-sqlite3 v1.14.23/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= +github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mcnijman/go-emailaddress v1.1.1 h1:AGhgVDG3tCDaL0/Vc6erlPQjDuDN3dAT7rRdgFtetr0= github.com/mcnijman/go-emailaddress v1.1.1/go.mod h1:5whZrhS8Xp5LxO8zOD35BC+b76kROtsh+dPomeRt/II= github.com/mikesmitty/edkey v0.0.0-20170222072505-3356ea4e686a h1:eU8j/ClY2Ty3qdHnn0TyW3ivFoPC/0F1gQZz8yTxbbE= @@ -122,8 +122,8 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWb github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 h1:Dx7Ovyv/SFnMFw3fD4oEoeorXc6saIiQ23LrGLth0Gw= -github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 h1:qli3BGQK0tYDkSEvZ/FzZTi9ZrOX86Q6CIhKLGc489A= +github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -159,10 +159,10 @@ github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/yuin/goldmark v1.7.6 h1:cZgJxVh5mL5cu8KOnwxvFJy5TFB0BHUskZZyq7TYbDg= -github.com/yuin/goldmark v1.7.6/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= -go.mau.fi/util v0.8.0 h1:MiSny8jgQq4XtCLAT64gDJhZVhqiDeMVIEBDFVw+M0g= -go.mau.fi/util v0.8.0/go.mod h1:1Ixb8HWoVbl3rT6nAX6nV4iMkzn7KU/KXwE0Rn5RmsQ= +github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic= +github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +go.mau.fi/util v0.8.1 h1:Ga43cz6esQBYqcjZ/onRoVnYWoUwjWbsxVeJg2jOTSo= +go.mau.fi/util v0.8.1/go.mod h1:T1u/rD2rzidVrBLyaUdPpZiJdP/rsyi+aTzn0D+Q6wc= golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= @@ -203,8 +203,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -maunium.net/go/mautrix v0.21.0 h1:Z6nVu+clkJgj6ANwFYQQ1BtYeVXZPZ9lRgwuFN57gOY= -maunium.net/go/mautrix v0.21.0/go.mod h1:qm9oDhcHxF/Xby5RUuONIGpXw1SXXqLZj/GgvMxJxu0= +maunium.net/go/mautrix v0.21.1 h1:Z+e448jtlY977iC1kokNJTH5kg2WmDpcQCqn+v9oZOA= +maunium.net/go/mautrix v0.21.1/go.mod h1:7F/S6XAdyc/6DW+Q7xyFXRSPb6IjfqMb1OMepQ8C8OE= modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= modernc.org/ccgo/v4 v4.21.0 h1:kKPI3dF7RIag8YcToh5ZwDcVMIv6VGa0ED5cvh0LMW4= diff --git a/internal/bot/data.go b/internal/bot/data.go index 240b496..834ab07 100644 --- a/internal/bot/data.go +++ b/internal/bot/data.go @@ -3,6 +3,7 @@ package bot import ( "context" "strconv" + "strings" "time" "maunium.net/go/mautrix/id" @@ -11,10 +12,12 @@ import ( ) func (b *Bot) addRoom(roomID id.RoomID, cfg config.Room) { - b.rooms.Store(cfg.Mailbox(), roomID) + mailbox := strings.ToLower(strings.TrimSpace(cfg.Mailbox())) + b.rooms.Store(mailbox, roomID) aliases := cfg.Aliases() if len(aliases) > 0 { for _, alias := range aliases { + alias = strings.ToLower(strings.TrimSpace(alias)) b.rooms.Store(alias, roomID) } } diff --git a/internal/email/utils.go b/internal/email/utils.go index f9f6fbe..cad2bdd 100644 --- a/internal/email/utils.go +++ b/internal/email/utils.go @@ -25,6 +25,7 @@ func MessageID(eventID id.EventID, domain string) string { // Address gets email address from a valid email address notation (eg: "Jane Doe" -> jane@example.com) func Address(email string) string { + email = strings.ToLower(strings.TrimSpace(email)) addr, _ := mail.ParseAddress(email) //nolint:errcheck // if it fails here, nothing will help if addr == nil { list := AddressList(email) @@ -42,6 +43,7 @@ func AddressList(emailList string) []string { if emailList == "" { return []string{} } + emailList = strings.ToLower(strings.TrimSpace(emailList)) list, _ := mail.ParseAddressList(emailList) //nolint:errcheck // if it fails here, nothing will help if len(list) == 0 { return []string{} diff --git a/internal/utils/mail.go b/internal/utils/mail.go index c4f67c4..2d210d4 100644 --- a/internal/utils/mail.go +++ b/internal/utils/mail.go @@ -26,6 +26,7 @@ func Hostname(email string) string { // EmailParts parses email address into mailbox, subaddress, and hostname func EmailParts(email string) (mailbox, sub, hostname string) { + email = strings.ToLower(strings.TrimSpace(email)) address, err := emailaddress.Parse(email) if err == nil { mailbox = address.LocalPart diff --git a/vendor/github.com/emersion/go-sasl/README.md b/vendor/github.com/emersion/go-sasl/README.md index 6bd47ba..f88d93e 100644 --- a/vendor/github.com/emersion/go-sasl/README.md +++ b/vendor/github.com/emersion/go-sasl/README.md @@ -1,7 +1,6 @@ # go-sasl -[![godocs.io](https://godocs.io/github.com/emersion/go-sasl?status.svg)](https://godocs.io/github.com/emersion/go-sasl) -[![Build Status](https://travis-ci.org/emersion/go-sasl.svg?branch=master)](https://travis-ci.org/emersion/go-sasl) +[![Go Reference](https://pkg.go.dev/badge/github.com/emersion/go-sasl.svg)](https://pkg.go.dev/github.com/emersion/go-sasl) A [SASL](https://tools.ietf.org/html/rfc4422) library written in Go. diff --git a/vendor/github.com/emersion/go-sasl/login.go b/vendor/github.com/emersion/go-sasl/login.go index 3847ee1..b6c4c33 100644 --- a/vendor/github.com/emersion/go-sasl/login.go +++ b/vendor/github.com/emersion/go-sasl/login.go @@ -36,54 +36,3 @@ func (a *loginClient) Next(challenge []byte) (response []byte, err error) { func NewLoginClient(username, password string) Client { return &loginClient{username, password} } - -// Authenticates users with an username and a password. -type LoginAuthenticator func(username, password string) error - -type loginState int - -const ( - loginNotStarted loginState = iota - loginWaitingUsername - loginWaitingPassword -) - -type loginServer struct { - state loginState - username, password string - authenticate LoginAuthenticator -} - -// A server implementation of the LOGIN authentication mechanism, as described -// in https://tools.ietf.org/html/draft-murchison-sasl-login-00. -// -// LOGIN is obsolete and should only be enabled for legacy clients that cannot -// be updated to use PLAIN. -func NewLoginServer(authenticator LoginAuthenticator) Server { - return &loginServer{authenticate: authenticator} -} - -func (a *loginServer) Next(response []byte) (challenge []byte, done bool, err error) { - switch a.state { - case loginNotStarted: - // Check for initial response field, as per RFC4422 section 3 - if response == nil { - challenge = []byte("Username:") - break - } - a.state++ - fallthrough - case loginWaitingUsername: - a.username = string(response) - challenge = []byte("Password:") - case loginWaitingPassword: - a.password = string(response) - err = a.authenticate(a.username, a.password) - done = true - default: - err = ErrUnexpectedClientResponse - } - - a.state++ - return -} diff --git a/vendor/github.com/etkecc/go-healthchecks/v2/.gitignore b/vendor/github.com/etkecc/go-healthchecks/v2/.gitignore index ace1063..eae9097 100644 --- a/vendor/github.com/etkecc/go-healthchecks/v2/.gitignore +++ b/vendor/github.com/etkecc/go-healthchecks/v2/.gitignore @@ -1 +1 @@ -/testdata +/cover.out diff --git a/vendor/github.com/etkecc/go-healthchecks/v2/.golangci.yml b/vendor/github.com/etkecc/go-healthchecks/v2/.golangci.yml new file mode 100644 index 0000000..f26380f --- /dev/null +++ b/vendor/github.com/etkecc/go-healthchecks/v2/.golangci.yml @@ -0,0 +1,141 @@ +run: + concurrency: 4 + timeout: 30m + issues-exit-code: 1 + tests: true + build-tags: [] + skip-dirs-use-default: true + skip-files: [] + modules-download-mode: readonly + +output: + formats: + - format: colored-line-number + print-issued-lines: true + print-linter-name: true + sort-results: true + +linters-settings: + decorder: + dec-order: + - const + - var + - type + - func + dogsled: + max-blank-identifiers: 3 + errcheck: + check-type-assertions: true + check-blank: true + errchkjson: + report-no-exported: true + exhaustive: + check: + - switch + - map + default-signifies-exhaustive: true + gocognit: + min-complexity: 15 + nestif: + min-complexity: 5 + gocritic: + enabled-tags: + - diagnostic + - style + - performance + gofmt: + simplify: true + rewrite-rules: + - pattern: 'interface{}' + replacement: 'any' + - pattern: 'a[b:len(a)]' + replacement: 'a[b:]' + gofumpt: + extra-rules: true + grouper: + const-require-single-const: true + import-require-single-import: true + var-require-single-var: true + misspell: + locale: US + usestdlibvars: + time-month: true + time-layout: true + crypto-hash: true + default-rpc-path: true + sql-isolation-level: true + tls-signature-scheme: true + constant-kind: true + unparam: + check-exported: true +linters: + disable-all: false + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - containedctx + - decorder + - dogsled + - dupl + - dupword + - durationcheck + - errcheck + - errchkjson + - errname + - errorlint + - exhaustive + - forcetypeassert + - gocognit + - gocritic + - gocyclo + - gofmt + - gofumpt + - goimports + - gosec + - gosimple + - gosmopolitan + - govet + - ineffassign + - makezero + - mirror + - misspell + - nestif + - nolintlint + - prealloc + - predeclared + - revive + - sqlclosecheck + - staticcheck + - unconvert + - unparam + - unused + - usestdlibvars + - wastedassign + fast: false + + +issues: + exclude-dirs: + - mocks + exclude-rules: + - path: _test\.go + linters: + - gocyclo + - gocognit + - errcheck + - dupl + - gosec + - linters: + - staticcheck + text: "SA9003:" + - linters: + - lll + source: "^//go:generate " + - linters: + - revive + text: "returns unexported type" + max-issues-per-linter: 0 + max-same-issues: 0 + new: false diff --git a/vendor/github.com/etkecc/go-healthchecks/v2/client.go b/vendor/github.com/etkecc/go-healthchecks/v2/client.go index 4579f6c..318dbbd 100644 --- a/vendor/github.com/etkecc/go-healthchecks/v2/client.go +++ b/vendor/github.com/etkecc/go-healthchecks/v2/client.go @@ -1,6 +1,7 @@ package healthchecks import ( + "errors" "fmt" "io" "net/http" @@ -46,20 +47,25 @@ func (c *Client) init(options ...Option) { } if c.uuid == "" { - randomUUID, _ := uuid.NewRandom() + randomUUID, _ := uuid.NewRandom() //nolint:errcheck // ignore error c.uuid = randomUUID.String() c.create = true c.log("uuid", fmt.Errorf("check UUID is not provided, using random %q with auto provision", c.uuid)) } } -// call API -func (c *Client) call(operation, endpoint string, body ...io.Reader) { +// Call API +func (c *Client) Call(operation, endpoint string, body ...io.Reader) { if !c.enabled { return } c.wg.Add(1) + go c.call(operation, endpoint, body...) +} + +// call API, extracted from c.Call to reduce cyclomatic complexity +func (c *Client) call(operation, endpoint string, body ...io.Reader) { defer c.wg.Done() targetURL := fmt.Sprintf("%s/%s%s?rid=%s", c.baseURL, c.uuid, endpoint, c.rid) @@ -94,7 +100,7 @@ func (c *Client) call(operation, endpoint string, body ...io.Reader) { c.log(operation+":response", rerr) return } - rerr = fmt.Errorf(string(respb)) + rerr = errors.New(string(respb)) c.log(operation+":response", rerr) return } @@ -109,27 +115,27 @@ func (c *Client) SetEnabled(enabled bool) { // Start signal means the job started func (c *Client) Start(optionalBody ...io.Reader) { - go c.call("start", "/start", optionalBody...) + c.Call("start", "/start", optionalBody...) } // Success signal means the job has completed successfully (or, a continuously running process is still running and healthy). func (c *Client) Success(optionalBody ...io.Reader) { - go c.call("success", "", optionalBody...) + c.Call("success", "", optionalBody...) } // Fail signal means the job failed func (c *Client) Fail(optionalBody ...io.Reader) { - go c.call("fail", "/fail", optionalBody...) + c.Call("fail", "/fail", optionalBody...) } // Log signal just adds an event to the job log, without changing job status func (c *Client) Log(optionalBody ...io.Reader) { - go c.call("log", "/log", optionalBody...) + c.Call("log", "/log", optionalBody...) } // ExitStatus signal sends job's exit code (0-255) func (c *Client) ExitStatus(exitCode int, optionalBody ...io.Reader) { - go c.call("exit status", "/"+strconv.Itoa(exitCode), optionalBody...) + c.Call("exit status", "/"+strconv.Itoa(exitCode), optionalBody...) } // Shutdown the client diff --git a/vendor/github.com/etkecc/go-healthchecks/v2/healthchecks.go b/vendor/github.com/etkecc/go-healthchecks/v2/healthchecks.go index a369fa7..5ea9383 100644 --- a/vendor/github.com/etkecc/go-healthchecks/v2/healthchecks.go +++ b/vendor/github.com/etkecc/go-healthchecks/v2/healthchecks.go @@ -26,7 +26,7 @@ var DefaultErrLog = func(operation string, err error) { // New healthchecks client func New(options ...Option) *Client { - rid, _ := uuid.NewRandom() + rid, _ := uuid.NewRandom() //nolint:errcheck // ignore error c := &Client{ rid: rid.String(), } diff --git a/vendor/github.com/etkecc/go-healthchecks/v2/justfile b/vendor/github.com/etkecc/go-healthchecks/v2/justfile index e016978..6a2428c 100644 --- a/vendor/github.com/etkecc/go-healthchecks/v2/justfile +++ b/vendor/github.com/etkecc/go-healthchecks/v2/justfile @@ -4,7 +4,7 @@ default: # update go deps update *flags: - go get {{flags}} . + go get {{ flags }} . go mod tidy # run linter diff --git a/vendor/github.com/etkecc/go-secgen/password.go b/vendor/github.com/etkecc/go-secgen/password.go index a2925c5..cb041e5 100644 --- a/vendor/github.com/etkecc/go-secgen/password.go +++ b/vendor/github.com/etkecc/go-secgen/password.go @@ -2,6 +2,7 @@ package secgen import ( "crypto/rand" + "crypto/sha512" "encoding/base64" "encoding/hex" "math/big" @@ -23,6 +24,12 @@ func Password(length int) string { return password.String() } +// Passphrase generates secure passphrase, based on shared secret and salt +func Passphrase(sharedSecret, salt string) string { + hash := sha512.Sum512([]byte(sharedSecret + salt)) + return base64.StdEncoding.EncodeToString(hash[:])[:64] +} + // Base64Bytes generates secure bytes with the given length and returns it as a base64 string func Base64Bytes(length int) string { randomBytes := make([]byte, length) diff --git a/vendor/github.com/yuin/goldmark/ast/ast.go b/vendor/github.com/yuin/goldmark/ast/ast.go index 67bb0da..36ba606 100644 --- a/vendor/github.com/yuin/goldmark/ast/ast.go +++ b/vendor/github.com/yuin/goldmark/ast/ast.go @@ -123,6 +123,12 @@ type Node interface { Dump(source []byte, level int) // Text returns text values of this node. + // This method is valid only for some inline nodes. + // If this node is a block node, Text returns a text value as reasonable as possible. + // Notice that there are no 'correct' text values for the block nodes. + // Result for the block nodes may be different from your expectation. + // + // Deprecated: Use other properties of the node to get the text value(i.e. Pragraph.Lines, Text.Value). Text(source []byte) []byte // HasBlankPreviousLines returns true if the row before this node is blank, @@ -374,11 +380,18 @@ func (n *BaseNode) OwnerDocument() *Document { return nil } -// Text implements Node.Text . +// Text implements Node.Text . +// +// Deprecated: Use other properties of the node to get the text value(i.e. Pragraph.Lines, Text.Value). func (n *BaseNode) Text(source []byte) []byte { var buf bytes.Buffer for c := n.firstChild; c != nil; c = c.NextSibling() { buf.Write(c.Text(source)) + if sb, ok := c.(interface { + SoftLineBreak() bool + }); ok && sb.SoftLineBreak() { + buf.WriteByte('\n') + } } return buf.Bytes() } diff --git a/vendor/github.com/yuin/goldmark/ast/block.go b/vendor/github.com/yuin/goldmark/ast/block.go index 04d0d54..eae7acd 100644 --- a/vendor/github.com/yuin/goldmark/ast/block.go +++ b/vendor/github.com/yuin/goldmark/ast/block.go @@ -1,7 +1,6 @@ package ast import ( - "bytes" "fmt" "strings" @@ -48,15 +47,6 @@ func (b *BaseBlock) SetLines(v *textm.Segments) { b.lines = v } -// Text implements Node.Text. -func (b *BaseBlock) Text(source []byte) []byte { - var buf bytes.Buffer - for _, line := range b.Lines().Sliced(0, b.Lines().Len()) { - buf.Write(line.Value(source)) - } - return buf.Bytes() -} - // A Document struct is a root node of Markdown text. type Document struct { BaseBlock @@ -140,6 +130,13 @@ func (n *TextBlock) Kind() NodeKind { return KindTextBlock } +// Text implements Node.Text. +// +// Deprecated: Use other properties of the node to get the text value(i.e. TextBlock.Lines). +func (n *TextBlock) Text(source []byte) []byte { + return n.Lines().Value(source) +} + // NewTextBlock returns a new TextBlock node. func NewTextBlock() *TextBlock { return &TextBlock{ @@ -165,6 +162,13 @@ func (n *Paragraph) Kind() NodeKind { return KindParagraph } +// Text implements Node.Text. +// +// Deprecated: Use other properties of the node to get the text value(i.e. Paragraph.Lines). +func (n *Paragraph) Text(source []byte) []byte { + return n.Lines().Value(source) +} + // NewParagraph returns a new Paragraph node. func NewParagraph() *Paragraph { return &Paragraph{ @@ -259,6 +263,13 @@ func (n *CodeBlock) Kind() NodeKind { return KindCodeBlock } +// Text implements Node.Text. +// +// Deprecated: Use other properties of the node to get the text value(i.e. CodeBlock.Lines). +func (n *CodeBlock) Text(source []byte) []byte { + return n.Lines().Value(source) +} + // NewCodeBlock returns a new CodeBlock node. func NewCodeBlock() *CodeBlock { return &CodeBlock{ @@ -314,6 +325,13 @@ func (n *FencedCodeBlock) Kind() NodeKind { return KindFencedCodeBlock } +// Text implements Node.Text. +// +// Deprecated: Use other properties of the node to get the text value(i.e. FencedCodeBlock.Lines). +func (n *FencedCodeBlock) Text(source []byte) []byte { + return n.Lines().Value(source) +} + // NewFencedCodeBlock return a new FencedCodeBlock node. func NewFencedCodeBlock(info *Text) *FencedCodeBlock { return &FencedCodeBlock{ @@ -508,6 +526,17 @@ func (n *HTMLBlock) Kind() NodeKind { return KindHTMLBlock } +// Text implements Node.Text. +// +// Deprecated: Use other properties of the node to get the text value(i.e. HTMLBlock.Lines). +func (n *HTMLBlock) Text(source []byte) []byte { + ret := n.Lines().Value(source) + if n.HasClosure() { + ret = append(ret, n.ClosureLine.Value(source)...) + } + return ret +} + // NewHTMLBlock returns a new HTMLBlock node. func NewHTMLBlock(typ HTMLBlockType) *HTMLBlock { return &HTMLBlock{ diff --git a/vendor/github.com/yuin/goldmark/ast/inline.go b/vendor/github.com/yuin/goldmark/ast/inline.go index 7e4c51f..613eb1e 100644 --- a/vendor/github.com/yuin/goldmark/ast/inline.go +++ b/vendor/github.com/yuin/goldmark/ast/inline.go @@ -143,17 +143,25 @@ func (n *Text) Merge(node Node, source []byte) bool { } // Text implements Node.Text. +// +// Deprecated: Use other properties of the node to get the text value(i.e. Text.Value). func (n *Text) Text(source []byte) []byte { return n.Segment.Value(source) } +// Value returns a value of this node. +// SoftLineBreaks are not included in the returned value. +func (n *Text) Value(source []byte) []byte { + return n.Segment.Value(source) +} + // Dump implements Node.Dump. func (n *Text) Dump(source []byte, level int) { fs := textFlagsString(n.flags) if len(fs) != 0 { fs = "(" + fs + ")" } - fmt.Printf("%sText%s: \"%s\"\n", strings.Repeat(" ", level), fs, strings.TrimRight(string(n.Text(source)), "\n")) + fmt.Printf("%sText%s: \"%s\"\n", strings.Repeat(" ", level), fs, strings.TrimRight(string(n.Value(source)), "\n")) } // KindText is a NodeKind of the Text node. @@ -258,6 +266,8 @@ func (n *String) SetCode(v bool) { } // Text implements Node.Text. +// +// Deprecated: Use other properties of the node to get the text value(i.e. String.Value). func (n *String) Text(source []byte) []byte { return n.Value } @@ -492,15 +502,22 @@ func (n *AutoLink) URL(source []byte) []byte { ret := make([]byte, 0, len(n.Protocol)+s.Len()+3) ret = append(ret, n.Protocol...) ret = append(ret, ':', '/', '/') - ret = append(ret, n.value.Text(source)...) + ret = append(ret, n.value.Value(source)...) return ret } - return n.value.Text(source) + return n.value.Value(source) } // Label returns a label of this node. func (n *AutoLink) Label(source []byte) []byte { - return n.value.Text(source) + return n.value.Value(source) +} + +// Text implements Node.Text. +// +// Deprecated: Use other properties of the node to get the text value(i.e. AutoLink.Label). +func (n *AutoLink) Text(source []byte) []byte { + return n.value.Value(source) } // NewAutoLink returns a new AutoLink node. @@ -541,6 +558,13 @@ func (n *RawHTML) Kind() NodeKind { return KindRawHTML } +// Text implements Node.Text. +// +// Deprecated: Use other properties of the node to get the text value(i.e. RawHTML.Segments). +func (n *RawHTML) Text(source []byte) []byte { + return n.Segments.Value(source) +} + // NewRawHTML returns a new RawHTML node. func NewRawHTML() *RawHTML { return &RawHTML{ diff --git a/vendor/github.com/yuin/goldmark/parser/code_block.go b/vendor/github.com/yuin/goldmark/parser/code_block.go index 732f18c..d99146c 100644 --- a/vendor/github.com/yuin/goldmark/parser/code_block.go +++ b/vendor/github.com/yuin/goldmark/parser/code_block.go @@ -35,6 +35,7 @@ func (b *codeBlockParser) Open(parent ast.Node, reader text.Reader, pc Context) if segment.Padding != 0 { preserveLeadingTabInCodeBlock(&segment, reader, 0) } + segment.ForceNewline = true node.Lines().Append(segment) reader.Advance(segment.Len() - 1) return node, NoChildren @@ -59,6 +60,7 @@ func (b *codeBlockParser) Continue(node ast.Node, reader text.Reader, pc Context preserveLeadingTabInCodeBlock(&segment, reader, 0) } + segment.ForceNewline = true node.Lines().Append(segment) reader.Advance(segment.Len() - 1) return Continue | NoChildren diff --git a/vendor/github.com/yuin/goldmark/parser/fcode_block.go b/vendor/github.com/yuin/goldmark/parser/fcode_block.go index e51a35a..953b8dc 100644 --- a/vendor/github.com/yuin/goldmark/parser/fcode_block.go +++ b/vendor/github.com/yuin/goldmark/parser/fcode_block.go @@ -100,6 +100,7 @@ func (b *fencedCodeBlockParser) Continue(node ast.Node, reader text.Reader, pc C if padding != 0 { preserveLeadingTabInCodeBlock(&seg, reader, fdata.indent) } + seg.ForceNewline = true // EOF as newline node.Lines().Append(seg) reader.AdvanceAndSetPadding(segment.Stop-segment.Start-pos-1, padding) return Continue | NoChildren diff --git a/vendor/github.com/yuin/goldmark/parser/parser.go b/vendor/github.com/yuin/goldmark/parser/parser.go index b59666c..b05db13 100644 --- a/vendor/github.com/yuin/goldmark/parser/parser.go +++ b/vendor/github.com/yuin/goldmark/parser/parser.go @@ -878,12 +878,6 @@ func (p *parser) Parse(reader text.Reader, opts ...ParseOption) ast.Node { blockReader := text.NewBlockReader(reader.Source(), nil) p.walkBlock(root, func(node ast.Node) { p.parseBlock(blockReader, node, pc) - lines := node.Lines() - if lines != nil && lines.Len() != 0 { - s := lines.At(lines.Len() - 1) - s.EOB = true - lines.Set(lines.Len()-1, s) - } }) for _, at := range p.astTransformers { at.Transform(root, reader, pc) diff --git a/vendor/github.com/yuin/goldmark/renderer/html/html.go b/vendor/github.com/yuin/goldmark/renderer/html/html.go index 9ebd0a3..aac8d2d 100644 --- a/vendor/github.com/yuin/goldmark/renderer/html/html.go +++ b/vendor/github.com/yuin/goldmark/renderer/html/html.go @@ -680,7 +680,7 @@ func (r *Renderer) renderImage(w util.BufWriter, source []byte, node ast.Node, e _, _ = w.Write(util.EscapeHTML(util.URLEscape(n.Destination, true))) } _, _ = w.WriteString(`" alt="`) - r.renderAttribute(w, source, n) + r.renderTexts(w, source, n) _ = w.WriteByte('"') if n.Title != nil { _, _ = w.WriteString(` title="`) @@ -737,7 +737,7 @@ func (r *Renderer) renderText(w util.BufWriter, source []byte, node ast.Node, en if r.EastAsianLineBreaks != EastAsianLineBreaksNone && len(value) != 0 { sibling := node.NextSibling() if sibling != nil && sibling.Kind() == ast.KindText { - if siblingText := sibling.(*ast.Text).Text(source); len(siblingText) != 0 { + if siblingText := sibling.(*ast.Text).Value(source); len(siblingText) != 0 { thisLastRune := util.ToRune(value, len(value)-1) siblingFirstRune, _ := utf8.DecodeRune(siblingText) if r.EastAsianLineBreaks.softLineBreak(thisLastRune, siblingFirstRune) { @@ -770,19 +770,14 @@ func (r *Renderer) renderString(w util.BufWriter, source []byte, node ast.Node, return ast.WalkContinue, nil } -func (r *Renderer) renderAttribute(w util.BufWriter, source []byte, n ast.Node) { +func (r *Renderer) renderTexts(w util.BufWriter, source []byte, n ast.Node) { for c := n.FirstChild(); c != nil; c = c.NextSibling() { if s, ok := c.(*ast.String); ok { _, _ = r.renderString(w, source, s, true) - } else if t, ok := c.(*ast.String); ok { + } else if t, ok := c.(*ast.Text); ok { _, _ = r.renderText(w, source, t, true) - } else if !c.HasChildren() { - r.Writer.Write(w, c.Text(source)) - if t, ok := c.(*ast.Text); ok && t.SoftLineBreak() { - _ = w.WriteByte('\n') - } } else { - r.renderAttribute(w, source, c) + r.renderTexts(w, source, c) } } } diff --git a/vendor/github.com/yuin/goldmark/text/segment.go b/vendor/github.com/yuin/goldmark/text/segment.go index 83c875b..93fbf19 100644 --- a/vendor/github.com/yuin/goldmark/text/segment.go +++ b/vendor/github.com/yuin/goldmark/text/segment.go @@ -20,8 +20,19 @@ type Segment struct { // Padding is a padding length of the segment. Padding int - // EOB is true if the segment is end of the block. - EOB bool + // ForceNewline is true if the segment should be ended with a newline. + // Some elements(i.e. CodeBlock, FencedCodeBlock) does not trim trailing + // newlines. Spec defines that EOF is treated as a newline, so we need to + // add a newline to the end of the segment if it is not empty. + // + // i.e.: + // + // ```go + // const test = "test" + // + // This code does not close the code block and ends with EOF. In this case, + // we need to add a newline to the end of the last line like `const test = "test"\n`. + ForceNewline bool } // NewSegment return a new Segment. @@ -52,7 +63,7 @@ func (t *Segment) Value(buffer []byte) []byte { result = append(result, bytes.Repeat(space, t.Padding)...) result = append(result, buffer[t.Start:t.Stop]...) } - if t.EOB && len(result) > 0 && result[len(result)-1] != '\n' { + if t.ForceNewline && len(result) > 0 && result[len(result)-1] != '\n' { result = append(result, '\n') } return result @@ -217,3 +228,12 @@ func (s *Segments) Unshift(v Segment) { s.values = append(s.values[0:1], s.values[0:]...) s.values[0] = v } + +// Value returns a string value of the collection. +func (s *Segments) Value(buffer []byte) []byte { + var result []byte + for _, v := range s.values { + result = append(result, v.Value(buffer)...) + } + return result +} diff --git a/vendor/go.mau.fi/util/dbutil/upgrades.go b/vendor/go.mau.fi/util/dbutil/upgrades.go index ae179ef..d2aa88f 100644 --- a/vendor/go.mau.fi/util/dbutil/upgrades.go +++ b/vendor/go.mau.fi/util/dbutil/upgrades.go @@ -110,14 +110,6 @@ func (db *Database) ColumnExists(ctx context.Context, table, column string) (exi return } -func (db *Database) tableExistsNoError(ctx context.Context, table string) bool { - exists, err := db.TableExists(ctx, table) - if err != nil { - panic(fmt.Errorf("failed to check if table exists: %w", err)) - } - return exists -} - const createOwnerTable = ` CREATE TABLE IF NOT EXISTS database_owner ( key INTEGER PRIMARY KEY DEFAULT 0, @@ -128,9 +120,13 @@ CREATE TABLE IF NOT EXISTS database_owner ( func (db *Database) checkDatabaseOwner(ctx context.Context) error { var owner string if !db.IgnoreForeignTables { - if db.tableExistsNoError(ctx, "state_groups_state") { + if exists, err := db.TableExists(ctx, "state_groups_state"); err != nil { + return fmt.Errorf("failed to check if state_groups_state exists: %w", err) + } else if exists { return fmt.Errorf("%w (found state_groups_state, likely belonging to Synapse)", ErrForeignTables) - } else if db.tableExistsNoError(ctx, "roomserver_rooms") { + } else if exists, err = db.TableExists(ctx, "roomserver_rooms"); err != nil { + return fmt.Errorf("failed to check if roomserver_rooms exists: %w", err) + } else if exists { return fmt.Errorf("%w (found roomserver_rooms, likely belonging to Dendrite)", ErrForeignTables) } } diff --git a/vendor/go.mau.fi/util/dbutil/upgradetable.go b/vendor/go.mau.fi/util/dbutil/upgradetable.go index 55e3818..dbf0143 100644 --- a/vendor/go.mau.fi/util/dbutil/upgradetable.go +++ b/vendor/go.mau.fi/util/dbutil/upgradetable.go @@ -78,7 +78,7 @@ var upgradeHeaderRegex = regexp.MustCompile(`^-- (?:v(\d+) -> )?v(\d+)(?: \(comp // -- v5: Upgrade without transaction // -- transaction: off // // do dangerous stuff -var transactionDisableRegex = regexp.MustCompile(`^-- transaction: (\w*)`) +var transactionDisableRegex = regexp.MustCompile(`^-- transaction: ([a-z-]*)`) func parseFileHeader(file []byte) (from, to, compat int, message string, txn TxnMode, lines [][]byte, err error) { lines = bytes.Split(file, []byte("\n")) diff --git a/vendor/go.mau.fi/util/exhttp/middleware.go b/vendor/go.mau.fi/util/exhttp/middleware.go new file mode 100644 index 0000000..733d348 --- /dev/null +++ b/vendor/go.mau.fi/util/exhttp/middleware.go @@ -0,0 +1,24 @@ +package exhttp + +import "net/http" + +// Middleware represents a middleware that can be applied to an [http.Handler]. +type Middleware func(http.Handler) http.Handler + +// ApplyMiddleware applies the provided [Middleware] functions to the given +// router. The middlewares will be applied in the order they are provided. +func ApplyMiddleware(router http.Handler, middlewares ...Middleware) http.Handler { + // Apply middlewares in reverse order because the first middleware provided + // needs to be the outermost one. + for i := len(middlewares) - 1; i >= 0; i-- { + router = middlewares[i](router) + } + return router +} + +// StripPrefix is a wrapper for [http.StripPrefix] is compatible with the middleware pattern. +func StripPrefix(prefix string) Middleware { + return func(next http.Handler) http.Handler { + return http.StripPrefix(prefix, next) + } +} diff --git a/vendor/maunium.net/go/mautrix/.pre-commit-config.yaml b/vendor/maunium.net/go/mautrix/.pre-commit-config.yaml index 1ef1b11..c15d69d 100644 --- a/vendor/maunium.net/go/mautrix/.pre-commit-config.yaml +++ b/vendor/maunium.net/go/mautrix/.pre-commit-config.yaml @@ -18,6 +18,8 @@ repos: - "-w" - id: go-vet-repo-mod - id: go-mod-tidy + # TODO enable this + #- id: go-staticcheck-repo-mod - repo: https://github.com/beeper/pre-commit-go rev: v0.3.1 diff --git a/vendor/maunium.net/go/mautrix/CHANGELOG.md b/vendor/maunium.net/go/mautrix/CHANGELOG.md index 661a71a..e190431 100644 --- a/vendor/maunium.net/go/mautrix/CHANGELOG.md +++ b/vendor/maunium.net/go/mautrix/CHANGELOG.md @@ -1,3 +1,14 @@ +## v0.21.1 (2024-10-16) + +* *(bridgev2)* Added more features and fixed bugs. +* *(hicli)* Added more features and fixed bugs. +* *(appservice)* Removed TLS support. A reverse proxy should be used if TLS + is needed. +* *(format/mdext)* Added goldmark extension to fix indented paragraphs when + disabling indented code block parser. +* *(event)* Added `Has` method for `Mentions`. +* *(event)* Added basic support for the unstable version of polls. + ## v0.21.0 (2024-09-16) * **Breaking change *(client)*** Dropped support for unauthenticated media. diff --git a/vendor/maunium.net/go/mautrix/client.go b/vendor/maunium.net/go/mautrix/client.go index b237612..b85d86f 100644 --- a/vendor/maunium.net/go/mautrix/client.go +++ b/vendor/maunium.net/go/mautrix/client.go @@ -420,6 +420,10 @@ func (params *FullRequest) compileRequest(ctx context.Context) (*http.Request, e params.RequestLength = int64(len(params.RequestBytes)) } else if params.RequestLength > 0 && params.RequestBody != nil { logBody = fmt.Sprintf("<%d bytes>", params.RequestLength) + if rsc, ok := params.RequestBody.(io.ReadSeekCloser); ok { + // Prevent HTTP from closing the request body, it might be needed for retries + reqBody = nopCloseSeeker{rsc} + } } else if params.Method != http.MethodGet && params.Method != http.MethodHead { params.RequestJSON = struct{}{} logBody = params.RequestJSON @@ -1465,6 +1469,18 @@ func (cli *Client) State(ctx context.Context, roomID id.RoomID) (stateMap RoomSt return } +// StateAsArray gets all the state in a room as an array. It does not update the state store. +// Use State to get the events as a map and also update the state store. +func (cli *Client) StateAsArray(ctx context.Context, roomID id.RoomID) (state []*event.Event, err error) { + _, err = cli.MakeRequest(ctx, http.MethodGet, cli.BuildClientURL("v3", "rooms", roomID, "state"), nil, &state) + if err == nil { + for _, evt := range state { + evt.Type.Class = event.StateEventType + } + } + return +} + // GetMediaConfig fetches the configuration of the content repository, such as upload limitations. func (cli *Client) GetMediaConfig(ctx context.Context) (resp *RespMediaConfig, err error) { _, err = cli.MakeRequest(ctx, http.MethodGet, cli.BuildClientURL("v1", "media", "config"), nil, &resp) @@ -1612,6 +1628,9 @@ func (cli *Client) uploadMediaToURL(ctx context.Context, data ReqUploadMedia) (* if data.ContentBytes != nil { data.ContentLength = int64(len(data.ContentBytes)) reader = bytes.NewReader(data.ContentBytes) + } else if rsc, ok := reader.(io.ReadSeekCloser); ok { + // Prevent HTTP from closing the request body, it might be needed for retries + reader = nopCloseSeeker{rsc} } readerSeeker, canSeek := reader.(io.ReadSeeker) if !canSeek { @@ -1656,6 +1675,14 @@ func (cli *Client) uploadMediaToURL(ctx context.Context, data ReqUploadMedia) (* return m, nil } +type nopCloseSeeker struct { + io.ReadSeeker +} + +func (nopCloseSeeker) Close() error { + return nil +} + // UploadMedia uploads the given data to the content repository and returns an MXC URI. // See https://spec.matrix.org/v1.7/client-server-api/#post_matrixmediav3upload func (cli *Client) UploadMedia(ctx context.Context, data ReqUploadMedia) (*RespMediaUpload, error) { @@ -1809,11 +1836,10 @@ func (cli *Client) Hierarchy(ctx context.Context, roomID id.RoomID, req *ReqHier // Messages returns a list of message and state events for a room. It uses // pagination query parameters to paginate history in the room. -// See https://spec.matrix.org/v1.2/client-server-api/#get_matrixclientv3roomsroomidmessages +// See https://spec.matrix.org/v1.12/client-server-api/#get_matrixclientv3roomsroomidmessages func (cli *Client) Messages(ctx context.Context, roomID id.RoomID, from, to string, dir Direction, filter *FilterPart, limit int) (resp *RespMessages, err error) { query := map[string]string{ - "from": from, - "dir": string(dir), + "dir": string(dir), } if filter != nil { filterJSON, err := json.Marshal(filter) @@ -1822,6 +1848,9 @@ func (cli *Client) Messages(ctx context.Context, roomID id.RoomID, from, to stri } query["filter"] = string(filterJSON) } + if from != "" { + query["from"] = from + } if to != "" { query["to"] = to } diff --git a/vendor/maunium.net/go/mautrix/crypto/cross_sign_store.go b/vendor/maunium.net/go/mautrix/crypto/cross_sign_store.go index 968a52a..b583bad 100644 --- a/vendor/maunium.net/go/mautrix/crypto/cross_sign_store.go +++ b/vendor/maunium.net/go/mautrix/crypto/cross_sign_store.go @@ -51,7 +51,7 @@ func (mach *OlmMachine) storeCrossSigningKeys(ctx context.Context, crossSigningK for _, key := range userKeys.Keys { log := log.With().Str("key", key.String()).Array("usages", exzerolog.ArrayOfStrs(userKeys.Usage)).Logger() for _, usage := range userKeys.Usage { - log.Debug().Str("usage", string(usage)).Msg("Storing cross-signing key") + log.Trace().Str("usage", string(usage)).Msg("Storing cross-signing key") if err = mach.CryptoStore.PutCrossSigningKey(ctx, userID, usage, key); err != nil { log.Error().Err(err).Msg("Error storing cross-signing key") } @@ -77,16 +77,16 @@ func (mach *OlmMachine) storeCrossSigningKeys(ctx context.Context, crossSigningK } } if len(signingKey) != 43 { - log.Debug().Msg("Cross-signing key has a signature from an unknown key") + log.Trace().Msg("Cross-signing key has a signature from an unknown key") continue } - log.Debug().Msg("Verifying cross-signing key signature") + log.Trace().Msg("Verifying cross-signing key signature") if verified, err := signatures.VerifySignatureJSON(userKeys, signUserID, signKeyName, signingKey); err != nil { log.Warn().Err(err).Msg("Error verifying cross-signing key signature") } else { if verified { - log.Debug().Err(err).Msg("Cross-signing key signature verified") + log.Trace().Err(err).Msg("Cross-signing key signature verified") err = mach.CryptoStore.PutSignature(ctx, userID, key, signUserID, signingKey, signature) if err != nil { log.Error().Err(err).Msg("Error storing cross-signing key signature") diff --git a/vendor/maunium.net/go/mautrix/crypto/machine.go b/vendor/maunium.net/go/mautrix/crypto/machine.go index c130f77..c9fc224 100644 --- a/vendor/maunium.net/go/mautrix/crypto/machine.go +++ b/vendor/maunium.net/go/mautrix/crypto/machine.go @@ -11,6 +11,7 @@ import ( "errors" "fmt" "sync" + "sync/atomic" "time" "github.com/rs/zerolog" @@ -67,7 +68,7 @@ type OlmMachine struct { otkUploadLock sync.Mutex lastOTKUpload time.Time - receivedOTKsForSelf bool + receivedOTKsForSelf atomic.Bool CrossSigningKeys *CrossSigningKeysCache crossSigningPubkeys *CrossSigningPublicKeysCache @@ -258,16 +259,18 @@ func (mach *OlmMachine) otkCountIsForCrossSigningKey(otkCount *mautrix.OTKCount) } func (mach *OlmMachine) HandleOTKCounts(ctx context.Context, otkCount *mautrix.OTKCount) { + receivedOTKsForSelf := mach.receivedOTKsForSelf.Load() if (len(otkCount.UserID) > 0 && otkCount.UserID != mach.Client.UserID) || (len(otkCount.DeviceID) > 0 && otkCount.DeviceID != mach.Client.DeviceID) { - if otkCount.UserID != mach.Client.UserID || (!mach.receivedOTKsForSelf && !mach.otkCountIsForCrossSigningKey(otkCount)) { + if otkCount.UserID != mach.Client.UserID || (!receivedOTKsForSelf && !mach.otkCountIsForCrossSigningKey(otkCount)) { mach.Log.Warn(). Str("target_user_id", otkCount.UserID.String()). Str("target_device_id", otkCount.DeviceID.String()). Msg("Dropping OTK counts targeted to someone else") } return + } else if !receivedOTKsForSelf { + mach.receivedOTKsForSelf.Store(true) } - mach.receivedOTKsForSelf = true minCount := mach.account.Internal.MaxNumberOfOneTimeKeys() / 2 if otkCount.SignedCurve25519 < int(minCount) { diff --git a/vendor/maunium.net/go/mautrix/error.go b/vendor/maunium.net/go/mautrix/error.go index 2f9ab98..a4ba985 100644 --- a/vendor/maunium.net/go/mautrix/error.go +++ b/vendor/maunium.net/go/mautrix/error.go @@ -162,6 +162,11 @@ func (e RespError) WithMessage(msg string, args ...any) RespError { return e } +func (e RespError) WithStatus(status int) RespError { + e.StatusCode = status + return e +} + // Error returns the errcode and error message. func (e RespError) Error() string { return e.ErrCode + ": " + e.Err diff --git a/vendor/maunium.net/go/mautrix/event/beeper.go b/vendor/maunium.net/go/mautrix/event/beeper.go index 1394a6c..911bdfe 100644 --- a/vendor/maunium.net/go/mautrix/event/beeper.go +++ b/vendor/maunium.net/go/mautrix/event/beeper.go @@ -97,3 +97,10 @@ type BeeperProfileExtra struct { IsBridgeBot bool `json:"com.beeper.bridge.is_bridge_bot,omitempty"` IsNetworkBot bool `json:"com.beeper.bridge.is_network_bot,omitempty"` } + +type BeeperPerMessageProfile struct { + ID string `json:"id"` + Displayname string `json:"displayname,omitempty"` + AvatarURL *id.ContentURIString `json:"avatar_url,omitempty"` + AvatarFile *EncryptedFileInfo `json:"avatar_file,omitempty"` +} diff --git a/vendor/maunium.net/go/mautrix/event/content.go b/vendor/maunium.net/go/mautrix/event/content.go index d08acad..882d336 100644 --- a/vendor/maunium.net/go/mautrix/event/content.go +++ b/vendor/maunium.net/go/mautrix/event/content.go @@ -55,6 +55,9 @@ var TypeMap = map[Type]reflect.Type{ EventRedaction: reflect.TypeOf(RedactionEventContent{}), EventReaction: reflect.TypeOf(ReactionEventContent{}), + EventUnstablePollStart: reflect.TypeOf(PollStartEventContent{}), + EventUnstablePollResponse: reflect.TypeOf(PollResponseEventContent{}), + BeeperMessageStatus: reflect.TypeOf(BeeperMessageStatusEventContent{}), AccountDataRoomTags: reflect.TypeOf(TagEventContent{}), diff --git a/vendor/maunium.net/go/mautrix/event/message.go b/vendor/maunium.net/go/mautrix/event/message.go index 3c6edfd..9badd9a 100644 --- a/vendor/maunium.net/go/mautrix/event/message.go +++ b/vendor/maunium.net/go/mautrix/event/message.go @@ -143,6 +143,27 @@ type MessageEventContent struct { MSC3245Voice *MSC3245Voice `json:"org.matrix.msc3245.voice,omitempty"` } +func (content *MessageEventContent) GetFileName() string { + if content.FileName != "" { + return content.FileName + } + return content.Body +} + +func (content *MessageEventContent) GetCaption() string { + if content.FileName != "" && content.Body != "" && content.Body != content.FileName { + return content.Body + } + return "" +} + +func (content *MessageEventContent) GetFormattedCaption() string { + if content.Format == FormatHTML && content.FormattedBody != "" { + return content.FormattedBody + } + return "" +} + func (content *MessageEventContent) GetRelatesTo() *RelatesTo { if content.RelatesTo == nil { content.RelatesTo = &RelatesTo{} @@ -220,6 +241,10 @@ func (m *Mentions) Add(userID id.UserID) { } } +func (m *Mentions) Has(userID id.UserID) bool { + return m != nil && slices.Contains(m.UserIDs, userID) +} + type EncryptedFileInfo struct { attachment.EncryptedFile URL id.ContentURIString `json:"url"` diff --git a/vendor/maunium.net/go/mautrix/event/poll.go b/vendor/maunium.net/go/mautrix/event/poll.go new file mode 100644 index 0000000..3733301 --- /dev/null +++ b/vendor/maunium.net/go/mautrix/event/poll.go @@ -0,0 +1,67 @@ +// Copyright (c) 2024 Tulir Asokan +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package event + +type PollResponseEventContent struct { + RelatesTo RelatesTo `json:"m.relates_to"` + Response struct { + Answers []string `json:"answers"` + } `json:"org.matrix.msc3381.poll.response"` +} + +func (content *PollResponseEventContent) GetRelatesTo() *RelatesTo { + return &content.RelatesTo +} + +func (content *PollResponseEventContent) OptionalGetRelatesTo() *RelatesTo { + if content.RelatesTo.Type == "" { + return nil + } + return &content.RelatesTo +} + +func (content *PollResponseEventContent) SetRelatesTo(rel *RelatesTo) { + content.RelatesTo = *rel +} + +type MSC1767Message struct { + Text string `json:"org.matrix.msc1767.text,omitempty"` + HTML string `json:"org.matrix.msc1767.html,omitempty"` + Message []struct { + MimeType string `json:"mimetype"` + Body string `json:"body"` + } `json:"org.matrix.msc1767.message,omitempty"` +} + +type PollStartEventContent struct { + RelatesTo *RelatesTo `json:"m.relates_to"` + Mentions *Mentions `json:"m.mentions,omitempty"` + PollStart struct { + Kind string `json:"kind"` + MaxSelections int `json:"max_selections"` + Question MSC1767Message `json:"question"` + Answers []struct { + ID string `json:"id"` + MSC1767Message + } `json:"answers"` + } `json:"org.matrix.msc3381.poll.start"` +} + +func (content *PollStartEventContent) GetRelatesTo() *RelatesTo { + if content.RelatesTo == nil { + content.RelatesTo = &RelatesTo{} + } + return content.RelatesTo +} + +func (content *PollStartEventContent) OptionalGetRelatesTo() *RelatesTo { + return content.RelatesTo +} + +func (content *PollStartEventContent) SetRelatesTo(rel *RelatesTo) { + content.RelatesTo = rel +} diff --git a/vendor/maunium.net/go/mautrix/event/profile.go b/vendor/maunium.net/go/mautrix/event/profile.go deleted file mode 100644 index 6dc4314..0000000 --- a/vendor/maunium.net/go/mautrix/event/profile.go +++ /dev/null @@ -1,10 +0,0 @@ -package event - -import "maunium.net/go/mautrix/id" - -type BeeperPerMessageProfile struct { - ID string `json:"id"` - Displayname string `json:"displayname,omitempty"` - AvatarURL *id.ContentURIString `json:"avatar_url,omitempty"` - AvatarFile *EncryptedFileInfo `json:"avatar_file,omitempty"` -} diff --git a/vendor/maunium.net/go/mautrix/event/type.go b/vendor/maunium.net/go/mautrix/event/type.go index 3f44734..4396c9c 100644 --- a/vendor/maunium.net/go/mautrix/event/type.go +++ b/vendor/maunium.net/go/mautrix/event/type.go @@ -126,7 +126,7 @@ func (et *Type) GuessClass() TypeClass { InRoomVerificationStart.Type, InRoomVerificationReady.Type, InRoomVerificationAccept.Type, InRoomVerificationKey.Type, InRoomVerificationMAC.Type, InRoomVerificationCancel.Type, CallInvite.Type, CallCandidates.Type, CallAnswer.Type, CallReject.Type, CallSelectAnswer.Type, - CallNegotiate.Type, CallHangup.Type, BeeperMessageStatus.Type: + CallNegotiate.Type, CallHangup.Type, BeeperMessageStatus.Type, EventUnstablePollStart.Type, EventUnstablePollResponse.Type: return MessageEventType case ToDeviceRoomKey.Type, ToDeviceRoomKeyRequest.Type, ToDeviceForwardedRoomKey.Type, ToDeviceRoomKeyWithheld.Type, ToDeviceBeeperRoomKeyAck.Type: @@ -232,6 +232,9 @@ var ( CallHangup = Type{"m.call.hangup", MessageEventType} BeeperMessageStatus = Type{"com.beeper.message_send_status", MessageEventType} + + EventUnstablePollStart = Type{Type: "org.matrix.msc3381.poll.start", Class: MessageEventType} + EventUnstablePollResponse = Type{Type: "org.matrix.msc3381.poll.response", Class: MessageEventType} ) // Ephemeral events diff --git a/vendor/maunium.net/go/mautrix/format/mdext/indentableparagraph.go b/vendor/maunium.net/go/mautrix/format/mdext/indentableparagraph.go new file mode 100644 index 0000000..a6ebd6c --- /dev/null +++ b/vendor/maunium.net/go/mautrix/format/mdext/indentableparagraph.go @@ -0,0 +1,28 @@ +// Copyright (c) 2024 Tulir Asokan +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package mdext + +import ( + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/util" +) + +// indentableParagraphParser is the default paragraph parser with CanAcceptIndentedLine. +// Used when disabling CodeBlockParser (as disabling it without a replacement will make indented blocks disappear). +type indentableParagraphParser struct { + parser.BlockParser +} + +var defaultIndentableParagraphParser = &indentableParagraphParser{BlockParser: parser.NewParagraphParser()} + +func (b *indentableParagraphParser) CanAcceptIndentedLine() bool { + return true +} + +// FixIndentedParagraphs is a goldmark option which fixes indented paragraphs when disabling CodeBlockParser. +var FixIndentedParagraphs = goldmark.WithParserOptions(parser.WithBlockParsers(util.Prioritized(defaultIndentableParagraphParser, 500))) diff --git a/vendor/maunium.net/go/mautrix/version.go b/vendor/maunium.net/go/mautrix/version.go index 80b9666..2936857 100644 --- a/vendor/maunium.net/go/mautrix/version.go +++ b/vendor/maunium.net/go/mautrix/version.go @@ -7,7 +7,7 @@ import ( "strings" ) -const Version = "v0.21.0" +const Version = "v0.21.1" var GoModVersion = "" var Commit = "" diff --git a/vendor/modules.txt b/vendor/modules.txt index 8f77978..8b8156a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -30,7 +30,7 @@ github.com/dustin/go-humanize # github.com/emersion/go-msgauth v0.6.8 ## explicit; go 1.18 github.com/emersion/go-msgauth/dkim -# github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 +# github.com/emersion/go-sasl v0.0.0-20241020182733-b788ff22d5a6 ## explicit; go 1.12 github.com/emersion/go-sasl # github.com/emersion/go-smtp v0.21.3 @@ -43,10 +43,10 @@ github.com/etkecc/go-env/dotenv # github.com/etkecc/go-fswatcher v1.0.1 ## explicit; go 1.20 github.com/etkecc/go-fswatcher -# github.com/etkecc/go-healthchecks/v2 v2.2.1 +# github.com/etkecc/go-healthchecks/v2 v2.2.2 ## explicit; go 1.18 github.com/etkecc/go-healthchecks/v2 -# github.com/etkecc/go-linkpearl v0.0.0-20240916112808-1ff87355b2b3 +# github.com/etkecc/go-linkpearl v0.0.0-20241016081935-715b568101ef ## explicit; go 1.22.0 github.com/etkecc/go-linkpearl # github.com/etkecc/go-mxidwc v1.0.1 @@ -55,7 +55,7 @@ github.com/etkecc/go-mxidwc # github.com/etkecc/go-psd v0.0.0-20241014083754-1bc4ec777ba8 ## explicit; go 1.21.0 github.com/etkecc/go-psd -# github.com/etkecc/go-secgen v1.3.0 +# github.com/etkecc/go-secgen v1.4.0 ## explicit; go 1.19 github.com/etkecc/go-secgen # github.com/etkecc/go-trysmtp v1.1.5 @@ -155,7 +155,7 @@ github.com/ncruces/go-strftime # github.com/olekukonko/tablewriter v0.0.5 ## explicit; go 1.12 github.com/olekukonko/tablewriter -# github.com/petermattis/goid v0.0.0-20240813172612-4fcff4a6cae7 +# github.com/petermattis/goid v0.0.0-20241025130422-66cb2e6d7274 ## explicit; go 1.17 github.com/petermattis/goid # github.com/pkg/errors v0.9.1 @@ -194,7 +194,7 @@ github.com/tidwall/pretty # github.com/tidwall/sjson v1.2.5 ## explicit; go 1.14 github.com/tidwall/sjson -# github.com/yuin/goldmark v1.7.6 +# github.com/yuin/goldmark v1.7.8 ## explicit; go 1.19 github.com/yuin/goldmark github.com/yuin/goldmark/ast @@ -205,7 +205,7 @@ github.com/yuin/goldmark/renderer github.com/yuin/goldmark/renderer/html github.com/yuin/goldmark/text github.com/yuin/goldmark/util -# go.mau.fi/util v0.8.0 +# go.mau.fi/util v0.8.1 ## explicit; go 1.22.0 go.mau.fi/util/base58 go.mau.fi/util/confusable @@ -288,7 +288,7 @@ golang.org/x/tools/internal/versions # gopkg.in/yaml.v2 v2.4.0 ## explicit; go 1.15 gopkg.in/yaml.v2 -# maunium.net/go/mautrix v0.21.0 +# maunium.net/go/mautrix v0.21.1 ## explicit; go 1.22.0 maunium.net/go/mautrix maunium.net/go/mautrix/crypto