Fix conversion to JSON, use ISO8601DateFormatter & clean

pull/36/head
Niels Andriesse 5 years ago
parent a9a403a703
commit a234019cb9

@ -1,4 +1,4 @@
platform :ios, '9.0'
platform :ios, '10.0'
source 'https://github.com/CocoaPods/Specs.git'
use_frameworks!

@ -3961,7 +3961,7 @@
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
INFOPLIST_FILE = SignalShareExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.share-extension";
@ -4026,7 +4026,7 @@
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = SignalShareExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.share-extension";
@ -4079,7 +4079,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
INFOPLIST_FILE = SignalMessaging/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.utilities";
@ -4152,7 +4152,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = SignalMessaging/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger.utilities";
@ -4366,7 +4366,7 @@
"\"$(SRCROOT)/Libraries\"/**",
);
INFOPLIST_FILE = "$(SRCROOT)/Signal/Signal-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
@ -4432,7 +4432,7 @@
"\"$(SRCROOT)/Libraries\"/**",
);
INFOPLIST_FILE = "$(SRCROOT)/Signal/Signal-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",

@ -1,81 +1,71 @@
import PromiseKit
public enum LokiGroupChatAPIError: Error {
case failedToParseMessage
case failedToParseTimestamp
}
@objc(LKGroupChatAPI)
public final class LokiGroupChatAPI : NSObject {
internal static let storage = OWSPrimaryStorage.shared()
internal static let contactsManager = SSKEnvironment.shared.contactsManager
internal static var userHexEncodedPublicKey: String { return OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey }
@objc public static let serverURL = "https://chat.lokinet.org"
private static let batchCount = 8
@objc public static let publicChatMessageType = "network.loki.messenger.publicChat"
@objc public static let publicChatID = 1
private static let batchCount = 8
internal static var userDisplayName: String {
return SSKEnvironment.shared.contactsManager.displayName(forPhoneIdentifier: userHexEncodedPublicKey) ?? "Anonymous"
}
public static func getMessages(for groupID: UInt) -> Promise<[LokiGroupMessage]> {
print("[Loki] Getting messages for group chat with ID: \(groupID)")
let url = URL(string: "\(serverURL)/channels/\(groupID)/messages?include_annotations=1&count=-\(batchCount)")!
private static var userHexEncodedPublicKey: String {
return OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey
}
public enum Error : Swift.Error {
case messageParsingFailed
}
public static func getMessages(for group: UInt) -> Promise<[LokiGroupMessage]> {
print("[Loki] Getting messages for group chat with ID: \(group).")
let queryParameters = "include_annotations=1&count=-\(batchCount)"
let url = URL(string: "\(serverURL)/channels/\(group)/messages?\(queryParameters)")!
let request = TSRequest(url: url)
return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in
guard let json = rawResponse as? JSON, let rawMessages = json["data"] as? [JSON] else {
print("[Loki] Failed to parse group messages from: \(rawResponse).")
return []
print("[Loki] Couldn't parse messages for group chat with ID: \(group) from: \(rawResponse).")
throw Error.messageParsingFailed
}
return rawMessages.flatMap { message in
guard let annotations = message["annotations"] as? [JSON], let annotation = annotations.first, let value = annotation["value"] as? JSON,
let serverID = message["id"] as? UInt, let body = message["text"] as? String, let hexEncodedPublicKey = value["source"] as? String, let displayName = value["from"] as? String, let timestamp = value["timestamp"] as? UInt64 else {
print("[Loki] Failed to parse message from: \(message).")
print("[Loki] Couldn't parse message for group chat with ID: \(group) from: \(message).")
return nil
}
guard hexEncodedPublicKey != userHexEncodedPublicKey else { return nil }
return LokiGroupMessage(serverID: serverID, hexEncodedPublicKey: hexEncodedPublicKey, displayName: displayName, body: body, type: publicChatMessageType, timestamp: timestamp)
}
}
}
public static func sendMessage(_ message: LokiGroupMessage, groupID: UInt) -> Promise<LokiGroupMessage> {
let url = URL(string: "\(serverURL)/channels/\(groupID)/messages")!
let request = TSRequest(url: url, method: "POST", parameters: message.toJSON())
request.allHTTPHeaderFields = [ "Authorization": "Bearer loki", "Content-Type": "application/json" ]
public static func sendMessage(_ message: LokiGroupMessage, to group: UInt) -> Promise<LokiGroupMessage> {
print("[Loki] Sending message to group chat with ID: \(group).")
let url = URL(string: "\(serverURL)/channels/\(group)/messages")!
let parameters = message.toJSON()
let request = TSRequest(url: url, method: "POST", parameters: parameters)
request.allHTTPHeaderFields = [ "Content-Type" : "application/json", "Authorization" : "Bearer loki" ]
let displayName = userDisplayName
return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in
guard let json = rawResponse as? JSON, let message = json["data"] as? JSON, let serverID = message["id"] as? UInt, let body = message["text"] as? String, let dateAsString = message["created_at"] as? String else {
print("[Loki] Failed to parse group messages from: \(rawResponse).")
throw LokiGroupChatAPIError.failedToParseMessage
}
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZ"
guard let date = formatter.date(from: dateAsString) else {
print("[Loki] Failed to parse message timestamp from: \(message).")
throw LokiGroupChatAPIError.failedToParseTimestamp
guard let json = rawResponse as? JSON, let message = json["data"] as? JSON, let serverID = message["id"] as? UInt, let body = message["text"] as? String, let dateAsString = message["created_at"] as? String, let date = ISO8601DateFormatter().date(from: dateAsString) else {
print("[Loki] Couldn't parse messages for group chat with ID: \(group) from: \(rawResponse).")
throw Error.messageParsingFailed
}
// Timestmap needs to be in milliseconds
let timestamp = UInt64(date.timeIntervalSince1970) * 1000
let displayName = contactsManager.displayName(forPhoneIdentifier: userHexEncodedPublicKey) ?? "Anonymous"
return LokiGroupMessage(serverID: serverID, hexEncodedPublicKey: userHexEncodedPublicKey, displayName: displayName, body: body, type: publicChatMessageType, timestamp: timestamp)
}
}
// MARK: Public API (Obj-C)
@objc(getMessagesForGroupID:)
public static func objc_getMessages(groupID: UInt) -> AnyPromise {
let promise = getMessages(for: groupID)
return AnyPromise.from(promise)
@objc(getMessagesForGroup:)
public static func objc_getMessages(for group: UInt) -> AnyPromise {
return AnyPromise.from(getMessages(for: group))
}
@objc(sendMessage:groupID:)
public static func objc_sendMessage(message: LokiGroupMessage, groupID: UInt) -> AnyPromise {
let promise = sendMessage(message, groupID: groupID)
return AnyPromise.from(promise)
@objc(sendMessage:toGroup:)
public static func objc_sendMessage(_ message: LokiGroupMessage, to group: UInt) -> AnyPromise {
return AnyPromise.from(sendMessage(message, to: group))
}
}

@ -1,15 +1,14 @@
import PromiseKit
@objc(LKGroupMessage)
public final class LokiGroupMessage: NSObject {
public final class LokiGroupMessage : NSObject {
let serverID: UInt?
let hexEncodedPublicKey: String
let displayName: String
let body: String
let type: String
/// - Note: Expressed as milliseconds since 00:00:00 UTC on 1 January 1970.
let timestamp: UInt64
let type: String
public init(serverID: UInt?, hexEncodedPublicKey: String, displayName: String, body: String, type: String, timestamp: UInt64) {
self.serverID = serverID
@ -26,7 +25,7 @@ public final class LokiGroupMessage: NSObject {
}
public func toJSON() -> JSON {
let value: JSON = [ "timestamp": timestamp, "from": displayName, "source": hexEncodedPublicKey ]
return [ "text": body, "annotations": [ "type": type, "value": value ] ]
let value: JSON = [ "timestamp" : timestamp, "from" : displayName, "source" : hexEncodedPublicKey ]
return [ "text" : body, "annotations": [ [ "type" : type, "value" : value ] ] ]
}
}

@ -1122,22 +1122,19 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[self messageSendDidFail:messageSend deviceMessages:deviceMessages statusCode:statusCode error:error responseData:responseData];
};
// Check to see if we're sending to a public channel
if ([recipient.recipientId isEqualToString:LKGroupChatAPI.serverURL]) {
NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
NSString *displayName = [SSKEnvironment.shared.contactsManager displayNameForPhoneIdentifier:userHexEncodedPublicKey];
if (displayName == nil) displayName = @"Anonymous";
if (displayName == nil) { displayName = @"Anonymous"; }
LKGroupMessage *groupMessage = [[LKGroupMessage alloc] initWithHexEncodedPublicKey:userHexEncodedPublicKey displayName:displayName body:message.body type:LKGroupChatAPI.publicChatMessageType timestamp:message.timestamp];
[[LKGroupChatAPI sendMessage:groupMessage groupID:LKGroupChatAPI.publicChatID]
.thenOn(OWSDispatch.sendingQueue, ^(id result) {
[[LKGroupChatAPI sendMessage:groupMessage toGroup:LKGroupChatAPI.publicChatID]
.thenOn(OWSDispatch.sendingQueue, ^(id result) {
[self messageSendDidSucceed:messageSend deviceMessages:deviceMessages wasSentByUD:false wasSentByWebsocket:false];
})
.catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { // The snode is unreachable
.catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { // The snode is unreachable
failedMessageSend(error);
}) retainUntilComplete];
} else {
// Gather the message info
NSDictionary *signalMessageInfo = deviceMessages.firstObject;
SSKProtoEnvelopeType type = ((NSNumber *)signalMessageInfo[@"type"]).integerValue;
uint64_t timestamp = message.timestamp;
@ -1181,7 +1178,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
__block NSUInteger errorCount = 0;
for (AnyPromise *promise in promises) {
[promise
.thenOn(OWSDispatch.sendingQueue, ^(id result) {
.thenOn(OWSDispatch.sendingQueue, ^(id result) {
if (isSuccess) { return; } // Succeed as soon as the first promise succeeds
isSuccess = YES;
if (signalMessage.type == TSFriendRequestMessageType) {
@ -1199,79 +1196,17 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
// Invoke the completion handler
[self messageSendDidSucceed:messageSend deviceMessages:deviceMessages wasSentByUD:false wasSentByWebsocket:false];
})
.catchOn(OWSDispatch.sendingQueue, ^(NSError *error) {
.catchOn(OWSDispatch.sendingQueue, ^(NSError *error) {
errorCount += 1;
if (errorCount != promiseCount) { return; } // Only error out if all promises failed
handleError(error);
}) retainUntilComplete];
}
})
.catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { // The snode is unreachable
.catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { // The snode is unreachable
handleError(error);
}) retainUntilComplete];
}
// Loki: Original code
/*
OWSRequestMaker *requestMaker = [[OWSRequestMaker alloc] initWithLabel:@"Message Send"
requestFactoryBlock:^(SMKUDAccessKey *_Nullable udAccessKey) {
return [OWSRequestFactory submitMessageRequestWithRecipient:recipient.recipientId
messages:deviceMessages
timeStamp:message.timestamp
udAccessKey:udAccessKey];
}
udAuthFailureBlock:^{
// Note the UD auth failure so subsequent retries
// to this recipient also use basic auth.
[messageSend setHasUDAuthFailed];
}
websocketFailureBlock:^{
// Note the websocket failure so subsequent retries
// to this recipient also use REST.
messageSend.hasWebsocketSendFailed = YES;
}
recipientId:recipient.recipientId
udAccess:messageSend.udAccess
canFailoverUDAuth:NO];
[[requestMaker makeRequestObjc]
.then(^(OWSRequestMakerResult *result) {
dispatch_async([OWSDispatch sendingQueue], ^{
[self messageSendDidSucceed:messageSend
deviceMessages:deviceMessages
wasSentByUD:result.wasSentByUD
wasSentByWebsocket:result.wasSentByWebsocket];
});
})
.catch(^(NSError *error) {
dispatch_async([OWSDispatch sendingQueue], ^{
NSUInteger statusCode = 0;
NSData *_Nullable responseData = nil;
if ([error.domain isEqualToString:@"SignalServiceKit.RequestMakerUDAuthError"]) {
// Try again.
OWSLogInfo(@"UD request auth failed; failing over to non-UD request.");
[error setIsRetryable:YES];
} else if ([error.domain isEqualToString:TSNetworkManagerErrorDomain]) {
statusCode = error.code;
NSError *_Nullable underlyingError = error.userInfo[NSUnderlyingErrorKey];
if (underlyingError) {
responseData
= underlyingError.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
} else {
OWSFailDebug(@"Missing underlying error: %@", error);
}
} else {
OWSFailDebug(@"Unexpected error: %@", error);
}
[self messageSendDidFail:messageSend
deviceMessages:deviceMessages
statusCode:statusCode
error:error
responseData:responseData];
});
}) retainUntilComplete];
*/
}
- (void)messageSendDidSucceed:(OWSMessageSend *)messageSend

Loading…
Cancel
Save