Repository navigation
feat(common-contacts): suggest recipients from the stack - #4998
MontaGhanmy wants to merge 11 commits into
Conversation
e50671a to
7e9e554
Compare
7e9e554 to
fdab2a3
Compare
25fffaa to
0a27e1f
Compare
| } | ||
| found[email] = doc | ||
| } | ||
| return found, nil |
There was a problem hiding this comment.
The contacts-by-email view emits addresses as stored, so Bob@Acme.example misses bob@acme.example.
Locally the suggestion came back without id or meta. Sharing to it then created a duplicate "Bob" contact with no instance URL, so a mail invite instead of cozy to cozy.
Querying both the address and its lowercase form, and keying the map by strings.ToLower, should do it. Same lookup in model/sharing/suggest.go L63-L70.
| return nil, nil | ||
| } | ||
| return docs, err | ||
| } |
There was a problem hiding this comment.
Two things here.
First, $regex through FindDocsUnoptimized is a full scan of the org instance, then of the user's instance, on every keystroke. With 20k members a query with no match takes 0.6s locally. Could the two calls run in parallel under a deadline? Or at least the docs could say contacts_search is expected in prod.
Second, CouchDB compiles the regex without UTF8, so (?i) only folds ASCII. q=élo misses Élodie. "(*UTF8)(?i)" + regexp.QuoteMeta(text) fixes it, and an accented test would be nice.
There was a problem hiding this comment.
Accents are fixed. For the scan: the side service is the main path (#4915), the regex is the degraded mode linagora/twake-workplace-private#1928 asked for, when contacts_search isn't set or the side service is down. It stops at limit matches, so the full scan is only the no-match case you measured.
| } | ||
| for _, c := range contacts { | ||
| add(c, SuggestionContact) | ||
| } |
There was a problem hiding this comment.
nit: members fill the limit first. With 20 matching members the user's own contact never shows up.
There was a problem hiding this comment.
On purpose, members go first so a member copied to the instance comes back as a member. It only affects the fallback: with the side service, the results keep its order.
| delete(s.Contact.M, "_rev") | ||
| data[i].Attributes = s.Contact.M | ||
| data[i].Meta = map[string]string{"kind": s.Kind} | ||
| } |
There was a problem hiding this comment.
This returns the whole org contact doc (phone, notes, carddavPath...) to any token with GET io.cozy.contacts on a member instance. Should it whitelist fullname, name, email and cozy?
Also, trashed contacts get suggested. Should they be filtered out?
There was a problem hiding this comment.
Trashed ones are filtered now. For the fields, nothing new: until #4970 every member was copied into each instance with name, email, phone and cozy URL, readable by the same token. The feed only adds carddavPath, no notes.
| t.Cleanup(ts.Close) | ||
| config.GetConfig().ContactsSearch = map[string]config.ContactsSearch{ | ||
| "acme": {URL: ts.URL + "/api/people/search", Token: "s3cr3t"}, | ||
| } |
There was a problem hiding this comment.
nit: ContactsSearch is set here without a t.Cleanup reset.
6ffcc94 to
0ab8429
Compare
36eeaf2 to
8362d62
Compare
7337a6e to
8fc77f2
Compare
eb885f5 to
6876dfc
Compare
e81976f to
d6bfe5e
Compare
… the organization
6876dfc to
36b88ed
Compare
Summary
GET /contacts/suggest?q=&limit=, with aGETpermission on the wholeio.cozy.contactsdoctype.qneeds 3 characters,limitdefaults to 20 and goes up to 256.common_contactsis enabled and the context is set incontacts_search, the stack asks the autocomplete API of the calendar side service, on behalf of theemailof the instance, for people with an email. The call times out after 1 second.meta.kind:memberwhen found on the org instance,contacton the user's instance. A result with no document comes back withoutidandmeta, with its name and email.common_contactsdisabled, withoutcontacts_search, or when the call fails or times out (logged), the stack runs a case-insensitive$regexMango query on names and emails, on both instances. Trashed contacts and contacts without an email are left out, and a member copied to the user's instance comes back once, as a member.contacts_searchis a top-level section keyed by context, likecommon_settings, and not undercontexts:GET /settings/contextreturns the context to any token, so the secret would leak. The ADR (docs: add contact suggestions adr #4915) needs the same change.hasFieldsuntil [COMMON CONTACT] hasField support twake-calendar-side-service#1109. Until then the stack drops results without an email, so a response can be shorter thanlimit.common_contacts; it does not change directory replication. The first backend rollout retains replication and leaves the existing sharing UI unchanged.Part of linagora/twake-workplace-private#1926, linagora/twake-workplace-private#1927 and linagora/twake-workplace-private#1928.