Skip to content

Commit

Permalink
merge devel
Browse files Browse the repository at this point in the history
  • Loading branch information
or-else committed Feb 21, 2023
2 parents a7f7f57 + fa5e599 commit c3d287b
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 17 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

Tinode is *not* XMPP/Jabber. It is *not* compatible with XMPP. It's meant as a replacement for XMPP. On the surface, it's a lot like open source WhatsApp or Telegram.

Version 0.20. This is beta-quality software: feature-complete and stable but probably with a few bugs or missing features. Follow [instructions](INSTALL.md) to install and run or use one of the cloud services below. Read [API documentation](docs/API.md).
This is beta-quality software: feature-complete and stable but probably with a few bugs or missing features. Follow [instructions](INSTALL.md) to install and run or use one of the cloud services below. Read [API documentation](docs/API.md).

<a href="https://apps.apple.com/us/app/tinode/id1483763538"><img src="docs/app-store.svg" height=36></a> <a href="https://play.google.com/store/apps/details?id=co.tinode.tindroidx"><img src="docs/play-store.svg" height=36></a> <a href="https://web.tinode.co/"><img src="docs/web-app.svg" height=36></a>

Expand Down
18 changes: 17 additions & 1 deletion docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -1280,7 +1280,7 @@ Tinode uses `{pres}` message to inform clients of important events. A separate [
pres: {
topic: "me", // string, topic which receives the notification, always present
src: "grp1XUtEhjv6HND", // string, topic or user affected by the change, always present
what: "on", // string, what's changed, always present
what: "on", // string, action type, what's changed, always present
seq: 123, // integer, "what" is "msg", a server-issued ID of the message,
// optional
clear: 15, // integer, "what" is "del", an update to the delete transaction ID.
Expand All @@ -1295,6 +1295,22 @@ pres: {
}
```

The following action types are currently defined:

* on: topic or user came online
* off: topic or user went offline
* ua: user agent changed, for example user was logged in with one client, then logged in with another
* upd: topic description has changed
* tags: topic tags have changed
* acs: access permissions have changed
* gone: topic is no longer available, for example, it was deleted or you were unsubscribed from it
* term: subscription to topic has been terminated, you may try to resubscribe
* msg: a new message is available
* read: one or more messages have been read by the recipient
* recv: one or more messages have been received by the recipient
* del: messages were deleted


The `{pres}` messages are purely transient: they are not stored and no attempt is made to deliver them later if the destination is temporarily unavailable.

Timestamp is not present in `{pres}` messages.
Expand Down
2 changes: 1 addition & 1 deletion server/hdl_files.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ func largeFileReceive(wrt http.ResponseWriter, req *http.Request) {
}

writeHttpResponse(NoErrParams(msgID, "", now, params), nil)
logs.Info.Println("media upload: ok", fdef.Location)
logs.Info.Println("media upload: ok", fdef.Id, fdef.Location)
}

// largeFileRunGarbageCollection runs every 'period' and deletes up to 'blockSize' unused files.
Expand Down
5 changes: 4 additions & 1 deletion server/media/media.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"net/http"
"path"
"regexp"
"strings"

"github.com/tinode/chat/server/store/types"
Expand Down Expand Up @@ -40,6 +41,8 @@ type Handler interface {
GetIdFromUrl(url string) types.Uid
}

var fileNamePattern = regexp.MustCompile(`^[-_A-Za-z0-9]+`)

// GetIdFromUrl is a helper method for extracting file ID from a URL.
func GetIdFromUrl(url, serveUrl string) types.Uid {
dir, fname := path.Split(path.Clean(url))
Expand All @@ -48,7 +51,7 @@ func GetIdFromUrl(url, serveUrl string) types.Uid {
return types.ZeroUid
}

return types.ParseUid(strings.Split(fname, ".")[0])
return types.ParseUid(fileNamePattern.FindString(fname))
}

// matchCORSOrigin compares origin from the HTTP request to a list of allowed origins.
Expand Down
13 changes: 13 additions & 0 deletions server/store/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -922,6 +922,9 @@ type Subscription struct {

// Topic's or user's state.
state ObjState

// This is not a fully initialized subscription object
dummy bool
}

// SetPublic assigns a value to `public`, otherwise not accessible from outside the package.
Expand Down Expand Up @@ -1032,6 +1035,16 @@ func (s *Subscription) SetState(state ObjState) {
s.state = state
}

// SetDummy marks this subscription object as only partially intialized.
func (s *Subscription) SetDummy(dummy bool) {
s.dummy = dummy
}

// IsDummy is true if this subscription object as only partially intialized.
func (s *Subscription) IsDummy() bool {
return s.dummy
}

// Contact is a result of a search for connections
type Contact struct {
Id string
Expand Down
36 changes: 31 additions & 5 deletions server/topic.go
Original file line number Diff line number Diff line change
Expand Up @@ -2368,6 +2368,30 @@ func (t *Topic) replyGetSub(sess *Session, asUid types.Uid, authLevel auth.Level
} else {
// User manages cache. Include deleted subscriptions too.
subs, err = store.Users.GetTopicsAny(asUid, msgOpts2storeOpts(req))

// Returned subscriptions do not contain topics which are online now but otherwise unchanged.
// We need to add these topic to the list otherwise the user would see them as offline.
selected := map[string]struct{}{}
for i := range subs {
sub := &subs[i]
with := sub.GetWith()
if with != "" {
selected[with] = struct{}{}
} else {
selected[sub.Topic] = struct{}{}
}
}

// Add dummy subscriptions for missing online topics.
for topic, psd := range t.perSubs {
_, present := selected[topic]
if !present && psd.online {
sub := types.Subscription{Topic: topic}
sub.SetWith(topic)
sub.SetDummy(true)
subs = append(subs, sub)
}
}
}
case types.TopicCatFnd:
// Select public or private query. Public has priority.
Expand Down Expand Up @@ -2500,15 +2524,15 @@ func (t *Topic) replyGetSub(sess *Session, asUid types.Uid, authLevel auth.Level

if !deleted && !banned {
if isReader {
if sub.GetTouchedAt().IsZero() {
touchedAt := sub.GetTouchedAt()
if touchedAt.IsZero() {
mts.TouchedAt = nil
} else {
touchedAt := sub.GetTouchedAt()
mts.TouchedAt = &touchedAt
}
mts.SeqId = sub.GetSeqId()
mts.DelId = sub.DelId
} else {
} else if !sub.UpdatedAt.IsZero() {
mts.TouchedAt = &sub.UpdatedAt
}

Expand Down Expand Up @@ -2546,15 +2570,17 @@ func (t *Topic) replyGetSub(sess *Session, asUid types.Uid, authLevel auth.Level
}

if !deleted {
mts.UpdatedAt = &sub.UpdatedAt
if !sub.UpdatedAt.IsZero() {
mts.UpdatedAt = &sub.UpdatedAt
}
if isReader && !banned {
mts.ReadSeqId = sub.ReadSeqId
mts.RecvSeqId = sub.RecvSeqId
}

if t.cat != types.TopicCatFnd {
// p2p and grp
if sharer || uid == asUid || subMode.IsAdmin() {
if !sub.IsDummy() && (sharer || uid == asUid || subMode.IsAdmin()) {
// If user is not a sharer, the access mode of other ordinary users if not accessible.
// Own and admin permissions only are visible to non-sharers.
mts.Acs.Mode = subMode.String()
Expand Down
14 changes: 7 additions & 7 deletions server/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,23 @@ func TestStringSliceDelta(t *testing.T) {
// - expected outputs: added, removed, intersection
cases := [][5][]string{
{
[]string{"abc", "def", "fff"}, []string{},
[]string{}, []string{"abc", "def", "fff"}, []string{},
{"abc", "def", "fff"}, {},
{}, {"abc", "def", "fff"}, {},
},
{
{}, {}, {}, {}, {},
},
{
{"aa", "xx", "bb", "aa", "bb"}, {"yy", "aa"},
{"yy"}, []string{"aa", "bb", "bb", "xx"}, []string{"aa"},
{"yy"}, {"aa", "bb", "bb", "xx"}, {"aa"},
},
{
[]string{"bb", "aa", "bb"}, []string{"yy", "aa", "bb", "zzz", "zzz", "cc"},
[]string{"cc", "yy", "zzz", "zzz"}, []string{"bb"}, []string{"aa", "bb"},
{"bb", "aa", "bb"}, {"yy", "aa", "bb", "zzz", "zzz", "cc"},
{"cc", "yy", "zzz", "zzz"}, {"bb"}, {"aa", "bb"},
},
{
[]string{"aa", "aa", "aa"}, []string{"aa", "aa", "aa"},
[]string{}, []string{}, []string{"aa", "aa", "aa"},
{"aa", "aa", "aa"}, {"aa", "aa", "aa"},
{}, {}, {"aa", "aa", "aa"},
},
}

Expand Down
2 changes: 1 addition & 1 deletion tn-cli/tn-cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def encode_to_bytes(src):
if src == None:
return None
if isinstance(src, str):
return src.encode('utf-8')
return ('"' + src + '"').encode()
return json.dumps(src).encode('utf-8')

# Parse credentials
Expand Down

0 comments on commit c3d287b

Please sign in to comment.