1
+ //
2
+ // Created by Jonathon Staff on 10/11/14.
3
+ // Copyright (c) 2014 Jonathon Staff. All rights reserved.
4
+ //
5
+
6
+ #import " XMPPRegistration.h"
7
+ #import " XMPPStream.h"
8
+ #import " XMPPIDTracker.h"
9
+ #import " XMPPIQ.h"
10
+ #import " NSXMLElement+XMPP.h"
11
+
12
+ NSString *const XMPPRegistrationErrorDomain = @" XMPPRegistrationErrorDomain" ;
13
+
14
+ @implementation XMPPRegistration
15
+
16
+ - (void )didActivate
17
+ {
18
+ xmppIDTracker = [[XMPPIDTracker alloc ] initWithStream: xmppStream dispatchQueue: moduleQueue];
19
+ }
20
+
21
+ - (void )willDeactivate
22
+ {
23
+ [xmppIDTracker removeAllIDs ];
24
+ xmppIDTracker = nil ;
25
+ }
26
+
27
+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
28
+ #pragma mark Public API
29
+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
30
+
31
+ - (BOOL )changePassword : (NSString *)newPassword
32
+ {
33
+ if (![xmppStream isAuthenticated ])
34
+ return NO ; // You must be authenticated in order to change your password
35
+
36
+ dispatch_block_t block = ^{
37
+ @autoreleasepool {
38
+ NSString *toStr = xmppStream.myJID .domain ;
39
+ NSXMLElement *query = [NSXMLElement elementWithName: @" query" xmlns: @" jabber:iq:register" ];
40
+
41
+ NSXMLElement *username = [NSXMLElement elementWithName: @" username"
42
+ stringValue: xmppStream.myJID.user];
43
+ NSXMLElement *password = [NSXMLElement elementWithName: @" password"
44
+ stringValue: newPassword];
45
+ [query addChild: username];
46
+ [query addChild: password];
47
+
48
+ XMPPIQ *iq = [XMPPIQ iqWithType: @" set"
49
+ to: [XMPPJID jidWithString: toStr]
50
+ elementID: [xmppStream generateUUID ]
51
+ child: query];
52
+
53
+ [xmppIDTracker addID: [iq elementID ]
54
+ target: self
55
+ selector: @selector (handlePasswordChangeQueryIQ:withInfo: )
56
+ timeout: 60 ];
57
+
58
+ [xmppStream sendElement: iq];
59
+ }
60
+ };
61
+
62
+ if (dispatch_get_specific (moduleQueueTag))
63
+ block ();
64
+ else
65
+ dispatch_async (moduleQueue, block);
66
+
67
+ return YES ;
68
+ }
69
+
70
+ - (BOOL )cancelRegistrationUsingPassword : (NSString *)password
71
+ {
72
+ // TODO: Handle the scenario of using password
73
+
74
+ dispatch_block_t block = ^{
75
+ @autoreleasepool {
76
+
77
+ NSXMLElement *remove = [NSXMLElement elementWithName: @" remove" ];
78
+ NSXMLElement *query = [NSXMLElement elementWithName: @" query" xmlns: @" jabber:iq:register" ];
79
+ [query addChild: remove];
80
+ XMPPIQ *iq = [XMPPIQ iqWithType: @" set"
81
+ elementID: [xmppStream generateUUID ]
82
+ child: query];
83
+
84
+ [xmppIDTracker addElement: iq
85
+ target: self
86
+ selector: @selector (handleRegistrationCancelQueryIQ:withInfo: )
87
+ timeout: 60 ];
88
+
89
+ [xmppStream sendElement: iq];
90
+ }
91
+ };
92
+
93
+ if (dispatch_get_specific (moduleQueueTag))
94
+ block ();
95
+ else
96
+ dispatch_async (moduleQueue, block);
97
+
98
+ return YES ;
99
+ }
100
+
101
+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
102
+ #pragma mark - XMPPIDTracker
103
+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
104
+
105
+ - (void )handlePasswordChangeQueryIQ : (XMPPIQ *)iq withInfo : (XMPPBasicTrackingInfo *)info
106
+ {
107
+ dispatch_block_t block = ^{
108
+ @autoreleasepool {
109
+ NSXMLElement *errorElem = [iq elementForName: @" error" ];
110
+
111
+ if (errorElem) {
112
+ NSString *errMsg = [[errorElem children ] componentsJoinedByString: @" , " ];
113
+ NSInteger errCode = [errorElem attributeIntegerValueForName: @" code"
114
+ withDefaultValue: -1 ];
115
+ NSDictionary *errInfo = @{NSLocalizedDescriptionKey : errMsg};
116
+ NSError *err = [NSError errorWithDomain: XMPPRegistrationErrorDomain
117
+ code: errCode
118
+ userInfo: errInfo];
119
+
120
+ [multicastDelegate passwordChangeFailed: self
121
+ withError: err];
122
+ return ;
123
+ }
124
+
125
+ NSString *type = [iq type ];
126
+
127
+ if ([type isEqualToString: @" result" ] && iq.childCount == 0 ) {
128
+ [multicastDelegate passwordChangeSuccessful: self ];
129
+ } else {
130
+ // this should be impossible to reach, but just for safety's sake...
131
+ [multicastDelegate passwordChangeFailed: self
132
+ withError: nil ];
133
+ }
134
+ }
135
+ };
136
+
137
+ if (dispatch_get_specific (moduleQueueTag))
138
+ block ();
139
+ else
140
+ dispatch_async (moduleQueue, block);
141
+ }
142
+
143
+ - (void )handleRegistrationCancelQueryIQ : (XMPPIQ *)iq withInfo : (XMPPBasicTrackingInfo *)info
144
+ {
145
+ dispatch_block_t block = ^{
146
+ @autoreleasepool {
147
+ NSXMLElement *errorElem = [iq elementForName: @" error" ];
148
+
149
+ if (errorElem) {
150
+ NSString *errMsg = [[errorElem children ] componentsJoinedByString: @" , " ];
151
+ NSInteger errCode = [errorElem attributeIntegerValueForName: @" code"
152
+ withDefaultValue: -1 ];
153
+ NSDictionary *errInfo = @{NSLocalizedDescriptionKey : errMsg};
154
+ NSError *err = [NSError errorWithDomain: XMPPRegistrationErrorDomain
155
+ code: errCode
156
+ userInfo: errInfo];
157
+
158
+ [multicastDelegate cancelRegistrationFailed: self
159
+ withError: err];
160
+ return ;
161
+ }
162
+
163
+ NSString *type = [iq type ];
164
+
165
+ if ([type isEqualToString: @" result" ] && iq.childCount == 0 ) {
166
+ [multicastDelegate cancelRegistrationSuccessful: self ];
167
+ } else {
168
+ // this should be impossible to reach, but just for safety's sake...
169
+ [multicastDelegate cancelRegistrationFailed: self
170
+ withError: nil ];
171
+ }
172
+ }
173
+ };
174
+
175
+ if (dispatch_get_specific (moduleQueueTag))
176
+ block ();
177
+ else
178
+ dispatch_async (moduleQueue, block);
179
+ }
180
+
181
+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
182
+ #pragma mark - XMPPStreamDelegate
183
+ // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
184
+
185
+ - (BOOL )xmppStream : (XMPPStream *)stream didReceiveIQ : (XMPPIQ *)iq
186
+ {
187
+ NSString *type = [iq type ];
188
+
189
+ if ([type isEqualToString: @" result" ] || [type isEqualToString: @" error" ]) {
190
+ NSLog (@" invoking with iq: %@ " , iq);
191
+ return [xmppIDTracker invokeForElement: iq withObject: iq];
192
+ }
193
+
194
+ return NO ;
195
+ }
196
+
197
+ @end
0 commit comments