vines 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +1 -1
- data/Rakefile +10 -10
- data/conf/certs/ca-bundle.crt +112 -378
- data/conf/config.rb +18 -9
- data/lib/vines.rb +8 -1
- data/lib/vines/command/cert.rb +2 -1
- data/lib/vines/command/init.rb +11 -0
- data/lib/vines/command/ldap.rb +6 -3
- data/lib/vines/command/schema.rb +1 -1
- data/lib/vines/config.rb +57 -146
- data/lib/vines/config/host.rb +85 -0
- data/lib/vines/config/port.rb +111 -0
- data/lib/vines/contact.rb +1 -1
- data/lib/vines/jid.rb +26 -4
- data/lib/vines/kit.rb +6 -0
- data/lib/vines/log.rb +24 -0
- data/lib/vines/router.rb +70 -38
- data/lib/vines/stanza.rb +45 -8
- data/lib/vines/stanza/iq.rb +3 -3
- data/lib/vines/stanza/iq/disco_info.rb +5 -1
- data/lib/vines/stanza/iq/disco_items.rb +3 -0
- data/lib/vines/stanza/iq/private_storage.rb +9 -5
- data/lib/vines/stanza/iq/roster.rb +11 -12
- data/lib/vines/stanza/iq/vcard.rb +4 -4
- data/lib/vines/stanza/iq/version.rb +25 -0
- data/lib/vines/stanza/message.rb +4 -5
- data/lib/vines/stanza/presence.rb +20 -18
- data/lib/vines/stanza/presence/probe.rb +3 -4
- data/lib/vines/stanza/presence/subscribe.rb +4 -3
- data/lib/vines/stanza/presence/subscribed.rb +6 -5
- data/lib/vines/stanza/presence/unsubscribe.rb +4 -4
- data/lib/vines/stanza/presence/unsubscribed.rb +4 -3
- data/lib/vines/storage/couchdb.rb +3 -3
- data/lib/vines/storage/ldap.rb +19 -8
- data/lib/vines/storage/local.rb +23 -12
- data/lib/vines/storage/redis.rb +3 -3
- data/lib/vines/storage/sql.rb +5 -5
- data/lib/vines/stream.rb +40 -6
- data/lib/vines/stream/client.rb +5 -6
- data/lib/vines/stream/client/auth.rb +3 -2
- data/lib/vines/stream/client/bind.rb +2 -2
- data/lib/vines/stream/client/bind_restart.rb +1 -2
- data/lib/vines/stream/client/ready.rb +2 -0
- data/lib/vines/stream/client/session.rb +13 -4
- data/lib/vines/stream/client/tls.rb +1 -0
- data/lib/vines/stream/component.rb +6 -5
- data/lib/vines/stream/component/ready.rb +5 -6
- data/lib/vines/stream/http.rb +10 -4
- data/lib/vines/stream/http/request.rb +23 -2
- data/lib/vines/stream/server.rb +13 -11
- data/lib/vines/stream/server/outbound/auth_result.rb +1 -0
- data/lib/vines/stream/server/outbound/tls_result.rb +1 -0
- data/lib/vines/stream/server/ready.rb +2 -2
- data/lib/vines/user.rb +2 -1
- data/lib/vines/version.rb +1 -1
- data/test/config/host_test.rb +292 -0
- data/test/config_test.rb +244 -103
- data/test/contact_test.rb +7 -1
- data/test/jid_test.rb +48 -0
- data/test/router_test.rb +16 -47
- data/test/stanza/iq/disco_info_test.rb +76 -0
- data/test/stanza/iq/disco_items_test.rb +47 -0
- data/test/stanza/iq/private_storage_test.rb +33 -10
- data/test/stanza/iq/roster_test.rb +15 -5
- data/test/stanza/iq/vcard_test.rb +8 -25
- data/test/stanza/iq/version_test.rb +62 -0
- data/test/stanza/iq_test.rb +13 -10
- data/test/stanza/message_test.rb +16 -24
- data/test/stanza/presence/probe_test.rb +52 -0
- data/test/stanza/presence/subscribe_test.rb +1 -5
- data/test/stanza_test.rb +77 -0
- data/test/stream/client/auth_test.rb +1 -0
- data/test/stream/client/ready_test.rb +2 -0
- data/test/stream/client/session_test.rb +7 -2
- data/test/stream/component/ready_test.rb +19 -36
- data/test/stream/http/request_test.rb +22 -2
- data/test/stream/server/ready_test.rb +14 -21
- data/web/404.html +9 -3
- data/web/chat/index.html +2 -2
- data/web/chat/javascripts/app.js +1 -1
- data/web/chat/stylesheets/chat.css +4 -9
- data/web/lib/coffeescripts/layout.coffee +2 -2
- data/web/{chat → lib}/coffeescripts/logout.coffee +0 -0
- data/web/lib/coffeescripts/notification.coffee +14 -0
- data/web/lib/coffeescripts/session.coffee +28 -24
- data/web/lib/coffeescripts/transfer.coffee +37 -34
- data/web/lib/javascripts/base.js +8 -8
- data/web/lib/javascripts/icons.js +3 -0
- data/web/lib/javascripts/jquery.js +4 -18
- data/web/lib/javascripts/layout.js +2 -2
- data/web/{chat → lib}/javascripts/logout.js +0 -0
- data/web/lib/javascripts/notification.js +26 -0
- data/web/lib/javascripts/session.js +20 -16
- data/web/lib/javascripts/transfer.js +45 -55
- data/web/lib/stylesheets/base.css +45 -9
- metadata +31 -15
data/lib/vines/stanza/iq.rb
CHANGED
@@ -33,11 +33,11 @@ module Vines
|
|
33
33
|
private
|
34
34
|
|
35
35
|
def route_iq
|
36
|
-
to =
|
37
|
-
return false if to.
|
36
|
+
to = validate_to
|
37
|
+
return false if to.nil? || to.to_s == stream.domain
|
38
38
|
self['from'] = stream.user.jid.to_s
|
39
39
|
if local?
|
40
|
-
|
40
|
+
stream.available_resources(to).each do |recipient|
|
41
41
|
recipient.write(@node)
|
42
42
|
end
|
43
43
|
else
|
@@ -13,9 +13,13 @@ module Vines
|
|
13
13
|
result = to_result.tap do |el|
|
14
14
|
el << el.document.create_element('query') do |query|
|
15
15
|
query.default_namespace = NS
|
16
|
+
query << el.document.create_element('identity', 'category' => 'server', 'type' => 'im')
|
17
|
+
query << el.document.create_element('feature', 'var' => NAMESPACES[:disco_info])
|
18
|
+
query << el.document.create_element('feature', 'var' => NAMESPACES[:disco_items])
|
16
19
|
query << el.document.create_element('feature', 'var' => NAMESPACES[:ping])
|
17
20
|
query << el.document.create_element('feature', 'var' => NAMESPACES[:vcard])
|
18
|
-
|
21
|
+
query << el.document.create_element('feature', 'var' => NAMESPACES[:version])
|
22
|
+
if stream.config.private_storage?(stream.domain)
|
19
23
|
query << el.document.create_element('feature', 'var' => NAMESPACES[:storage])
|
20
24
|
end
|
21
25
|
end
|
@@ -13,6 +13,9 @@ module Vines
|
|
13
13
|
result = to_result.tap do |el|
|
14
14
|
el << el.document.create_element('query') do |query|
|
15
15
|
query.default_namespace = NS
|
16
|
+
stream.config.vhosts[stream.domain].components.keys.sort.each do |domain|
|
17
|
+
query << el.document.create_element('item', 'jid' => domain)
|
18
|
+
end
|
16
19
|
end
|
17
20
|
end
|
18
21
|
stream.write(result)
|
@@ -12,10 +12,8 @@ module Vines
|
|
12
12
|
register "/iq[@id and (@type='get' or @type='set')]/ns:query", 'ns' => NS
|
13
13
|
|
14
14
|
def process
|
15
|
-
unless stream.private_storage?
|
16
|
-
raise StanzaErrors::ServiceUnavailable.new(self, 'cancel')
|
17
|
-
end
|
18
15
|
validate_to_address
|
16
|
+
validate_storage_enabled
|
19
17
|
validate_children_size
|
20
18
|
validate_namespaces
|
21
19
|
get? ? retrieve_fragment : update_fragment
|
@@ -64,12 +62,18 @@ module Vines
|
|
64
62
|
end
|
65
63
|
|
66
64
|
def validate_to_address
|
67
|
-
to =
|
68
|
-
unless to.
|
65
|
+
to = validate_to
|
66
|
+
unless to.nil? || to == stream.user.jid.bare
|
69
67
|
raise StanzaErrors::Forbidden.new(self, 'cancel')
|
70
68
|
end
|
71
69
|
end
|
72
70
|
|
71
|
+
def validate_storage_enabled
|
72
|
+
unless stream.config.private_storage?(stream.domain)
|
73
|
+
raise StanzaErrors::ServiceUnavailable.new(self, 'cancel')
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
73
77
|
def validate_namespaces
|
74
78
|
elements.first.elements.each do |node|
|
75
79
|
if node.namespace.nil? || NAMESPACES.values.include?(node.namespace.href)
|
@@ -9,6 +9,7 @@ module Vines
|
|
9
9
|
register "/iq[@id and (@type='get' or @type='set')]/ns:query", 'ns' => NS
|
10
10
|
|
11
11
|
def process
|
12
|
+
validate_to_address
|
12
13
|
get? ? roster_query : update_roster
|
13
14
|
end
|
14
15
|
|
@@ -26,8 +27,8 @@ module Vines
|
|
26
27
|
# Roster sets must have no 'to' address or be addressed to the same
|
27
28
|
# JID that sent the stanza. RFC 6121 sections 2.1.5 and 2.3.3.
|
28
29
|
def validate_to_address
|
29
|
-
to =
|
30
|
-
unless to.
|
30
|
+
to = validate_to
|
31
|
+
unless to.nil? || to.bare == stream.user.jid.bare
|
31
32
|
raise StanzaErrors::Forbidden.new(self, 'auth')
|
32
33
|
end
|
33
34
|
end
|
@@ -35,14 +36,12 @@ module Vines
|
|
35
36
|
# Add, update, or delete the roster item contained in the iq set
|
36
37
|
# stanza received from the client. RFC 6121 sections 2.3, 2.4, 2.5.
|
37
38
|
def update_roster
|
38
|
-
validate_to_address
|
39
|
-
|
40
39
|
items = self.xpath('ns:query/ns:item', 'ns' => NS)
|
41
40
|
raise StanzaErrors::BadRequest.new(self, 'modify') if items.size != 1
|
42
41
|
item = items.first
|
43
42
|
|
44
|
-
jid = (item['jid']
|
45
|
-
raise StanzaErrors::BadRequest.new(self, 'modify')
|
43
|
+
jid = JID.new(item['jid']) rescue (raise StanzaErrors::JidMalformed.new(self, 'modify'))
|
44
|
+
raise StanzaErrors::BadRequest.new(self, 'modify') if jid.empty? || !jid.bare?
|
46
45
|
|
47
46
|
if item['subscription'] == 'remove'
|
48
47
|
remove_contact(jid)
|
@@ -75,7 +74,7 @@ module Vines
|
|
75
74
|
def remove_contact(jid)
|
76
75
|
contact = stream.user.contact(jid)
|
77
76
|
raise StanzaErrors::ItemNotFound.new(self, 'modify') unless contact
|
78
|
-
if
|
77
|
+
if local_jid?(contact.jid)
|
79
78
|
user = storage(contact.jid.domain).find_user(contact.jid)
|
80
79
|
end
|
81
80
|
|
@@ -94,10 +93,10 @@ module Vines
|
|
94
93
|
:jid => contact.jid,
|
95
94
|
:subscription => 'remove'))
|
96
95
|
|
97
|
-
if
|
96
|
+
if local_jid?(contact.jid)
|
98
97
|
send_unavailable(stream.user.jid, contact.jid) if contact.subscribed_from?
|
99
98
|
send_unsubscribe(contact)
|
100
|
-
if user.contact(stream.user.jid)
|
99
|
+
if user && user.contact(stream.user.jid)
|
101
100
|
push_roster_updates(contact.jid, user.contact(stream.user.jid))
|
102
101
|
end
|
103
102
|
else
|
@@ -112,8 +111,8 @@ module Vines
|
|
112
111
|
presence(contact.jid, type) if contact.send("subscribed_#{meth}?")
|
113
112
|
end.compact
|
114
113
|
|
115
|
-
if
|
116
|
-
|
114
|
+
if local_jid?(contact.jid)
|
115
|
+
stream.interested_resources(contact.jid).each do |recipient|
|
117
116
|
presence.each {|el| recipient.write(el) }
|
118
117
|
end
|
119
118
|
else
|
@@ -133,7 +132,7 @@ module Vines
|
|
133
132
|
# Send an iq set stanza to the user's interested resources, letting them
|
134
133
|
# know their roster has been updated.
|
135
134
|
def push_roster_updates(to, contact)
|
136
|
-
|
135
|
+
stream.interested_resources(to).each do |recipient|
|
137
136
|
contact.send_roster_push(recipient)
|
138
137
|
end
|
139
138
|
end
|
@@ -20,8 +20,8 @@ module Vines
|
|
20
20
|
private
|
21
21
|
|
22
22
|
def vcard_query
|
23
|
-
|
24
|
-
jid =
|
23
|
+
to = validate_to
|
24
|
+
jid = to ? to.bare : stream.user.jid.bare
|
25
25
|
card = storage.find_vcard(jid)
|
26
26
|
|
27
27
|
raise StanzaErrors::ItemNotFound.new(self, 'cancel') unless card
|
@@ -38,8 +38,8 @@ module Vines
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def vcard_update
|
41
|
-
to =
|
42
|
-
unless to.
|
41
|
+
to = validate_to
|
42
|
+
unless to.nil? || to == stream.user.jid.bare
|
43
43
|
raise StanzaErrors::Forbidden.new(self, 'auth')
|
44
44
|
end
|
45
45
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Vines
|
4
|
+
class Stanza
|
5
|
+
class Iq
|
6
|
+
class Version < Query
|
7
|
+
NS = NAMESPACES[:version]
|
8
|
+
|
9
|
+
register "/iq[@id and @type='get']/ns:query", 'ns' => NS
|
10
|
+
|
11
|
+
def process
|
12
|
+
return if route_iq
|
13
|
+
result = to_result.tap do |node|
|
14
|
+
node << node.document.create_element('query') do |query|
|
15
|
+
query.default_namespace = NS
|
16
|
+
query << node.document.create_element('name', 'Vines')
|
17
|
+
query << node.document.create_element('version', VERSION)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
stream.write(result)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/vines/stanza/message.rb
CHANGED
@@ -5,8 +5,8 @@ module Vines
|
|
5
5
|
class Message < Stanza
|
6
6
|
register "/message"
|
7
7
|
|
8
|
-
TYPE,
|
9
|
-
VALID_TYPES
|
8
|
+
TYPE, FROM = %w[type from].map {|s| s.freeze }
|
9
|
+
VALID_TYPES = %w[chat error groupchat headline normal].freeze
|
10
10
|
|
11
11
|
VALID_TYPES.each do |type|
|
12
12
|
define_method "#{type}?" do
|
@@ -20,9 +20,8 @@ module Vines
|
|
20
20
|
end
|
21
21
|
|
22
22
|
if local?
|
23
|
-
to =
|
24
|
-
|
25
|
-
recipients = router.connected_resources(to)
|
23
|
+
to = validate_to || stream.user.jid.bare
|
24
|
+
recipients = stream.connected_resources(to)
|
26
25
|
if recipients.empty?
|
27
26
|
if user = storage(to.domain).find_user(to)
|
28
27
|
# TODO Implement offline messaging storage
|
@@ -14,7 +14,7 @@ module Vines
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def process
|
17
|
-
stream.last_broadcast_presence = @node.clone unless
|
17
|
+
stream.last_broadcast_presence = @node.clone unless validate_to
|
18
18
|
unless self['type'].nil?
|
19
19
|
raise StanzaErrors::BadRequest.new(self, 'modify')
|
20
20
|
end
|
@@ -23,26 +23,28 @@ module Vines
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def outbound?
|
26
|
-
|
26
|
+
!inbound?
|
27
27
|
end
|
28
28
|
|
29
29
|
def inbound?
|
30
|
-
stream.class == Vines::Stream::Server
|
30
|
+
stream.class == Vines::Stream::Server ||
|
31
|
+
stream.class == Vines::Stream::Component
|
31
32
|
end
|
32
33
|
|
33
34
|
def outbound_broadcast_presence
|
34
35
|
self['from'] = stream.user.jid.to_s
|
35
|
-
to
|
36
|
-
|
36
|
+
to = validate_to
|
37
|
+
type = (self['type'] || '').strip
|
38
|
+
initial = to.nil? && type.empty? && !stream.available?
|
37
39
|
|
38
|
-
recipients = if to.
|
40
|
+
recipients = if to.nil?
|
39
41
|
stream.available_subscribers
|
40
42
|
else
|
41
|
-
stream.user.subscribed_from?(to) ?
|
43
|
+
stream.user.subscribed_from?(to) ? stream.available_resources(to) : []
|
42
44
|
end
|
43
45
|
|
44
46
|
broadcast(recipients)
|
45
|
-
broadcast(
|
47
|
+
broadcast(stream.available_resources(stream.user.jid))
|
46
48
|
|
47
49
|
if initial
|
48
50
|
stream.available_subscribed_to_resources.each do |recipient|
|
@@ -53,6 +55,9 @@ module Vines
|
|
53
55
|
stream.write(el)
|
54
56
|
end
|
55
57
|
end
|
58
|
+
stream.remote_subscribed_to_contacts.each do |contact|
|
59
|
+
send_probe(contact.jid.bare)
|
60
|
+
end
|
56
61
|
stream.available!
|
57
62
|
end
|
58
63
|
|
@@ -60,12 +65,11 @@ module Vines
|
|
60
65
|
node = @node.clone
|
61
66
|
node['to'] = contact.jid.bare.to_s
|
62
67
|
router.route(node) rescue nil # ignore RemoteServerNotFound
|
63
|
-
send_probe(contact.jid.bare) if initial
|
64
68
|
end
|
65
69
|
end
|
66
70
|
|
67
71
|
def inbound_broadcast_presence
|
68
|
-
broadcast(
|
72
|
+
broadcast(stream.available_resources(validate_to))
|
69
73
|
end
|
70
74
|
|
71
75
|
private
|
@@ -78,7 +82,7 @@ module Vines
|
|
78
82
|
'id' => Kit.uuid,
|
79
83
|
'to' => to.bare.to_s,
|
80
84
|
'type' => 'probe')
|
81
|
-
router.route(probe)
|
85
|
+
router.route(probe) rescue nil # ignore RemoteServerNotFound
|
82
86
|
end
|
83
87
|
|
84
88
|
def auto_reply_to_subscription_request(from, type)
|
@@ -96,13 +100,11 @@ module Vines
|
|
96
100
|
# resource part from it so it's a bare jid. Return the bare JID object
|
97
101
|
# that was stamped.
|
98
102
|
def stamp_to
|
99
|
-
to =
|
100
|
-
raise StanzaErrors::BadRequest.new(self, 'modify')
|
101
|
-
to
|
102
|
-
|
103
|
-
|
104
|
-
self['to'] = to.to_s
|
105
|
-
to
|
103
|
+
to = validate_to
|
104
|
+
raise StanzaErrors::BadRequest.new(self, 'modify') unless to
|
105
|
+
to.bare.tap do |bare|
|
106
|
+
self['to'] = bare.to_s
|
107
|
+
end
|
106
108
|
end
|
107
109
|
end
|
108
110
|
end
|
@@ -16,15 +16,14 @@ module Vines
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def process_inbound
|
19
|
-
to =
|
20
|
-
raise StanzaErrors::BadRequest.new(self, 'modify')
|
21
|
-
to = JID.new(to)
|
19
|
+
to = validate_to
|
20
|
+
raise StanzaErrors::BadRequest.new(self, 'modify') unless to
|
22
21
|
|
23
22
|
user = storage(to.domain).find_user(to)
|
24
23
|
unless user && user.subscribed_from?(stream.user.jid)
|
25
24
|
auto_reply_to_subscription_request(to.bare, 'unsubscribed')
|
26
25
|
else
|
27
|
-
|
26
|
+
stream.available_resources(to).each do |recipient|
|
28
27
|
el = recipient.last_broadcast_presence.clone
|
29
28
|
el['from'] = recipient.user.jid.to_s
|
30
29
|
el['to'] = stream.user.jid.to_s
|
@@ -13,14 +13,15 @@ module Vines
|
|
13
13
|
def process_outbound
|
14
14
|
self['from'] = stream.user.jid.bare.to_s
|
15
15
|
to = stamp_to
|
16
|
-
local? ? process_inbound : route
|
17
16
|
|
18
17
|
stream.user.request_subscription(to)
|
19
18
|
storage.save_user(stream.user)
|
20
19
|
stream.update_user_streams(stream.user)
|
21
20
|
|
21
|
+
local? ? process_inbound : route
|
22
|
+
|
22
23
|
contact = stream.user.contact(to)
|
23
|
-
|
24
|
+
stream.interested_resources(stream.user.jid).each do |recipient|
|
24
25
|
contact.send_roster_push(recipient)
|
25
26
|
end
|
26
27
|
end
|
@@ -35,7 +36,7 @@ module Vines
|
|
35
36
|
elsif contact.subscribed_from?(stream.user.jid)
|
36
37
|
auto_reply_to_subscription_request(to, 'subscribed')
|
37
38
|
else
|
38
|
-
recipients =
|
39
|
+
recipients = stream.available_resources(to)
|
39
40
|
if recipients.empty?
|
40
41
|
# TODO store subscription request per RFC 6121 3.1.3 #4
|
41
42
|
else
|
@@ -13,18 +13,19 @@ module Vines
|
|
13
13
|
def process_outbound
|
14
14
|
self['from'] = stream.user.jid.bare.to_s
|
15
15
|
to = stamp_to
|
16
|
-
local? ? process_inbound : route
|
17
16
|
|
18
17
|
stream.user.add_subscription_from(to)
|
19
18
|
storage.save_user(stream.user)
|
20
19
|
stream.update_user_streams(stream.user)
|
21
20
|
|
21
|
+
local? ? process_inbound : route
|
22
|
+
|
22
23
|
contact = stream.user.contact(to)
|
23
|
-
|
24
|
+
stream.interested_resources(stream.user.jid).each do |recipient|
|
24
25
|
contact.send_roster_push(recipient)
|
25
26
|
end
|
26
27
|
|
27
|
-
presences =
|
28
|
+
presences = stream.available_resources(stream.user.jid).map do |c|
|
28
29
|
c.last_broadcast_presence.clone.tap do |node|
|
29
30
|
node['from'] = c.user.jid.to_s
|
30
31
|
node['id'] = Kit.uuid
|
@@ -33,7 +34,7 @@ module Vines
|
|
33
34
|
end
|
34
35
|
|
35
36
|
if local?
|
36
|
-
|
37
|
+
stream.available_resources(to).each do |recipient|
|
37
38
|
presences.each {|el| recipient.write(el) }
|
38
39
|
end
|
39
40
|
else
|
@@ -52,7 +53,7 @@ module Vines
|
|
52
53
|
storage(to.domain).save_user(user)
|
53
54
|
stream.update_user_streams(user)
|
54
55
|
|
55
|
-
|
56
|
+
stream.interested_resources(to).each do |recipient|
|
56
57
|
recipient.write(@node)
|
57
58
|
contact.send_roster_push(recipient)
|
58
59
|
end
|
@@ -15,14 +15,14 @@ module Vines
|
|
15
15
|
to = stamp_to
|
16
16
|
|
17
17
|
return unless stream.user.subscribed_to?(to)
|
18
|
-
local? ? process_inbound : route
|
19
|
-
|
20
18
|
stream.user.remove_subscription_to(to)
|
21
19
|
storage.save_user(stream.user)
|
22
20
|
stream.update_user_streams(stream.user)
|
23
21
|
|
22
|
+
local? ? process_inbound : route
|
23
|
+
|
24
24
|
contact = stream.user.contact(to)
|
25
|
-
|
25
|
+
stream.interested_resources(stream.user.jid).each do |recipient|
|
26
26
|
contact.send_roster_push(recipient)
|
27
27
|
end
|
28
28
|
end
|
@@ -38,7 +38,7 @@ module Vines
|
|
38
38
|
storage(to.domain).save_user(user)
|
39
39
|
stream.update_user_streams(user)
|
40
40
|
|
41
|
-
|
41
|
+
stream.interested_resources(to).each do |recipient|
|
42
42
|
recipient.write(@node)
|
43
43
|
contact.send_roster_push(recipient)
|
44
44
|
end
|
@@ -16,14 +16,15 @@ module Vines
|
|
16
16
|
|
17
17
|
return unless stream.user.subscribed_from?(to)
|
18
18
|
send_unavailable(stream.user.jid, to)
|
19
|
-
local? ? process_inbound : route
|
20
19
|
|
21
20
|
stream.user.remove_subscription_from(to)
|
22
21
|
storage.save_user(stream.user)
|
23
22
|
stream.update_user_streams(stream.user)
|
24
23
|
|
24
|
+
local? ? process_inbound : route
|
25
|
+
|
25
26
|
contact = stream.user.contact(to)
|
26
|
-
|
27
|
+
stream.interested_resources(stream.user.jid).each do |recipient|
|
27
28
|
contact.send_roster_push(recipient)
|
28
29
|
end
|
29
30
|
end
|
@@ -39,7 +40,7 @@ module Vines
|
|
39
40
|
storage(to.domain).save_user(user)
|
40
41
|
stream.update_user_streams(user)
|
41
42
|
|
42
|
-
|
43
|
+
stream.interested_resources(to).each do |recipient|
|
43
44
|
recipient.write(@node)
|
44
45
|
contact.send_roster_push(recipient)
|
45
46
|
end
|