Truncate message times to the second when using the FS message store
The FS message store truncates message times to the second. This means that a message sent out as 2020-01-01T00:00:00.123Z could be sent later as part of a CHATHISTORY batch as 2020-01-01T00:00:00.000Z, which could cause issues in clients. One such issue is a client sending a MARKREAD for 2020-01-01T00:00:00.000Z, with another client considering the 2020-01-01T00:00:00.123Z message it has as unread. This fixes the issue by truncating all message times to the second when using the FS message store.
This commit is contained in:
parent
87b2d32682
commit
897c21dbb4
@ -2281,7 +2281,7 @@ func (dc *downstreamConn) handleMessageRegistered(ctx context.Context, msg *irc.
|
|||||||
dc.logger.Printf("broadcasting bouncer-wide %v: %v", msg.Command, text)
|
dc.logger.Printf("broadcasting bouncer-wide %v: %v", msg.Command, text)
|
||||||
|
|
||||||
broadcastTags := tags.Copy()
|
broadcastTags := tags.Copy()
|
||||||
broadcastTags["time"] = xirc.FormatServerTime(time.Now())
|
broadcastTags["time"] = dc.user.FormatServerTime(time.Now())
|
||||||
broadcastMsg := &irc.Message{
|
broadcastMsg := &irc.Message{
|
||||||
Tags: broadcastTags,
|
Tags: broadcastTags,
|
||||||
Prefix: servicePrefix,
|
Prefix: servicePrefix,
|
||||||
@ -2307,7 +2307,7 @@ func (dc *downstreamConn) handleMessageRegistered(ctx context.Context, msg *irc.
|
|||||||
if casemapASCII(name) == serviceNickCM {
|
if casemapASCII(name) == serviceNickCM {
|
||||||
if dc.caps.IsEnabled("echo-message") {
|
if dc.caps.IsEnabled("echo-message") {
|
||||||
echoTags := tags.Copy()
|
echoTags := tags.Copy()
|
||||||
echoTags["time"] = xirc.FormatServerTime(time.Now())
|
echoTags["time"] = dc.user.FormatServerTime(time.Now())
|
||||||
dc.SendMessage(&irc.Message{
|
dc.SendMessage(&irc.Message{
|
||||||
Tags: echoTags,
|
Tags: echoTags,
|
||||||
Prefix: dc.prefix(),
|
Prefix: dc.prefix(),
|
||||||
@ -2351,7 +2351,7 @@ func (dc *downstreamConn) handleMessageRegistered(ctx context.Context, msg *irc.
|
|||||||
}
|
}
|
||||||
|
|
||||||
echoTags := tags.Copy()
|
echoTags := tags.Copy()
|
||||||
echoTags["time"] = xirc.FormatServerTime(time.Now())
|
echoTags["time"] = dc.user.FormatServerTime(time.Now())
|
||||||
if uc.account != "" {
|
if uc.account != "" {
|
||||||
echoTags["account"] = uc.account
|
echoTags["account"] = uc.account
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,11 @@ var (
|
|||||||
_ RenameNetworkStore = (*fsMessageStore)(nil)
|
_ RenameNetworkStore = (*fsMessageStore)(nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func IsFSStore(store Store) bool {
|
||||||
|
_, ok := store.(*fsMessageStore)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
func NewFSStore(root string, user *database.User) *fsMessageStore {
|
func NewFSStore(root string, user *database.User) *fsMessageStore {
|
||||||
return &fsMessageStore{
|
return &fsMessageStore{
|
||||||
root: filepath.Join(root, escapeFilename(user.Username)),
|
root: filepath.Join(root, escapeFilename(user.Username)),
|
||||||
|
@ -486,8 +486,12 @@ func (uc *upstreamConn) handleMessage(ctx context.Context, msg *irc.Message) err
|
|||||||
msg.Prefix = uc.serverPrefix
|
msg.Prefix = uc.serverPrefix
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := msg.Tags["time"]; !ok && !isNumeric(msg.Command) {
|
if !isNumeric(msg.Command) {
|
||||||
msg.Tags["time"] = xirc.FormatServerTime(time.Now())
|
t, err := time.Parse(xirc.ServerTimeLayout, string(msg.Tags["time"]))
|
||||||
|
if err != nil {
|
||||||
|
t = time.Now()
|
||||||
|
}
|
||||||
|
msg.Tags["time"] = uc.user.FormatServerTime(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch msg.Command {
|
switch msg.Command {
|
||||||
|
11
user.go
11
user.go
@ -13,6 +13,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"git.sr.ht/~emersion/soju/xirc"
|
||||||
|
|
||||||
"github.com/SherClockHolmes/webpush-go"
|
"github.com/SherClockHolmes/webpush-go"
|
||||||
"gopkg.in/irc.v4"
|
"gopkg.in/irc.v4"
|
||||||
|
|
||||||
@ -1114,6 +1116,15 @@ func (u *user) hasPersistentMsgStore() bool {
|
|||||||
return !msgstore.IsMemoryStore(u.msgStore)
|
return !msgstore.IsMemoryStore(u.msgStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (u *user) FormatServerTime(t time.Time) string {
|
||||||
|
if u.msgStore != nil && msgstore.IsFSStore(u.msgStore) {
|
||||||
|
// The FS message store truncates message timestamps to the second,
|
||||||
|
// so truncate them here to get consistent timestamps.
|
||||||
|
t = t.Truncate(time.Second)
|
||||||
|
}
|
||||||
|
return xirc.FormatServerTime(t)
|
||||||
|
}
|
||||||
|
|
||||||
// localAddrForHost returns the local address to use when connecting to host.
|
// localAddrForHost returns the local address to use when connecting to host.
|
||||||
// A nil address is returned when the OS should automatically pick one.
|
// A nil address is returned when the OS should automatically pick one.
|
||||||
func (u *user) localTCPAddrForHost(ctx context.Context, host string) (*net.TCPAddr, error) {
|
func (u *user) localTCPAddrForHost(ctx context.Context, host string) (*net.TCPAddr, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user