parent
5c481c38ba
commit
2694699e4e
2
Pods
2
Pods
|
@ -1 +1 @@
|
|||
Subproject commit 6174a578a93622fc02184ba8983fc809ef7bc0ec
|
||||
Subproject commit e5dc17be2dc588fde41caa91484aa9e6b9c56ebd
|
|
@ -7,7 +7,7 @@
|
|||
<key>CarthageVersion</key>
|
||||
<string>0.33.0</string>
|
||||
<key>OSXVersion</key>
|
||||
<string>10.14.5</string>
|
||||
<string>10.14.4</string>
|
||||
<key>WebRTCCommit</key>
|
||||
<string>1445d719bf05280270e9f77576f80f973fd847f8 M73</string>
|
||||
</dict>
|
||||
|
|
|
@ -320,6 +320,7 @@ static NSTimeInterval launchStartedAt;
|
|||
if (self.lokiP2PServer.isRunning) { break; }
|
||||
BOOL isStarted = [self.lokiP2PServer startOnPort:port.unsignedIntegerValue];
|
||||
if (isStarted) {
|
||||
[LokiAPI setOurP2PAddressWithUrl:self.lokiP2PServer.serverURL];
|
||||
OWSLogInfo(@"[Loki] Started server at %@.", self.lokiP2PServer.serverURL);
|
||||
break;
|
||||
}
|
||||
|
@ -751,7 +752,8 @@ static NSTimeInterval launchStartedAt;
|
|||
// Loki: Start poller
|
||||
[Poller.shared startIfNeeded];
|
||||
|
||||
// TODO: Ping friends to let them know we're online
|
||||
// Loki: Tell our friends that we are online
|
||||
[LokiAPI broadcastOnlineStatus];
|
||||
|
||||
if (![UIApplication sharedApplication].isRegisteredForRemoteNotifications) {
|
||||
OWSLogInfo(@"Retrying to register for remote notifications since user hasn't registered yet.");
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
|
||||
extension LokiAPI {
|
||||
private static let messageSender: MessageSender = SSKEnvironment.shared.messageSender
|
||||
internal static var ourP2PAddress: Target? = nil
|
||||
|
||||
/// Set our local P2P address
|
||||
///
|
||||
/// - Parameter url: The url to our local server
|
||||
@objc public static func setOurP2PAddress(url: URL) {
|
||||
guard let port = url.port else { return }
|
||||
let target = Target(address: url.absoluteString, port: UInt32(port))
|
||||
ourP2PAddress = target
|
||||
}
|
||||
|
||||
/// Broadcash an online message to all our friends.
|
||||
/// This shouldn't be called inside a transaction.
|
||||
@objc public static func broadcastOnlineStatus() {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
let friendThreads = getAllFriendThreads()
|
||||
for thread in friendThreads {
|
||||
sendOnlineBroadcastMessage(forThread: thread)
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the `LokiAddressMessage` for the given thread.
|
||||
///
|
||||
/// - Parameter thread: The contact thread.
|
||||
/// - Returns: The `LokiAddressMessage` for that thread.
|
||||
@objc public static func onlineBroadcastMessage(forThread thread: TSThread) -> LokiAddressMessage? {
|
||||
guard let ourAddress = ourP2PAddress else {
|
||||
Logger.error("P2P Address not set")
|
||||
return nil
|
||||
}
|
||||
|
||||
return LokiAddressMessage(in: thread, address: ourAddress.address, port: ourAddress.port)
|
||||
}
|
||||
|
||||
/// Send a `Loki Address` message to the given thread
|
||||
///
|
||||
/// - Parameter thread: The contact thread to send the message to
|
||||
@objc public static func sendOnlineBroadcastMessage(forThread thread: TSContactThread) {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
guard let message = onlineBroadcastMessage(forThread: thread) else {
|
||||
owsFailDebug("P2P Address not set")
|
||||
return
|
||||
}
|
||||
|
||||
messageSender.sendPromise(message: message).catch { error in
|
||||
Logger.warn("Failed to send online status to \(thread.contactIdentifier())")
|
||||
}
|
||||
}
|
||||
|
||||
@objc public static func sendOnlineBroadcastMessage(forThread thread: TSContactThread, transaction: YapDatabaseReadWriteTransaction) {
|
||||
guard let ourAddress = ourP2PAddress else {
|
||||
owsFailDebug("P2P Address not set")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
private static func getAllFriendThreads() -> [TSContactThread] {
|
||||
var friendThreadIds = [String]()
|
||||
TSContactThread.enumerateCollectionObjects { (object, _) in
|
||||
guard let thread = object as? TSContactThread, let uniqueId = thread.uniqueId else { return }
|
||||
|
||||
if thread.friendRequestStatus == .friends && thread.contactIdentifier() != ourHexEncodedPubKey {
|
||||
friendThreadIds.append(thread.uniqueId!)
|
||||
}
|
||||
}
|
||||
|
||||
return friendThreadIds.compactMap { TSContactThread.fetch(uniqueId: $0) }
|
||||
}
|
||||
|
||||
}
|
|
@ -4,7 +4,7 @@ extension LokiAPI {
|
|||
|
||||
// MARK: Settings
|
||||
private static let targetSnodeCount = 2
|
||||
private static let defaultSnodePort: UInt16 = 8080
|
||||
private static let defaultSnodePort: UInt32 = 8080
|
||||
|
||||
// MARK: Caching
|
||||
private static var swarmCache: [String:[Target]] = [:]
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
import PromiseKit
|
||||
|
||||
@objc public final class LokiAPI : NSObject {
|
||||
private static let storage = OWSPrimaryStorage.shared()
|
||||
internal static let storage = OWSPrimaryStorage.shared()
|
||||
|
||||
// MARK: Settings
|
||||
private static let version = "v1"
|
||||
public static let defaultMessageTTL: UInt64 = 1 * 24 * 60 * 60
|
||||
|
||||
internal static let ourHexEncodedPubKey = OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey
|
||||
|
||||
// MARK: Types
|
||||
internal struct Target : Hashable {
|
||||
let address: String
|
||||
let port: UInt16
|
||||
let port: UInt32
|
||||
|
||||
enum Method : String {
|
||||
/// Only applicable to snode targets.
|
||||
|
@ -46,10 +48,9 @@ import PromiseKit
|
|||
|
||||
// MARK: Public API
|
||||
public static func getMessages() -> Promise<Set<Promise<[SSKProtoEnvelope]>>> {
|
||||
let hexEncodedPublicKey = OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey
|
||||
return getTargetSnodes(for: hexEncodedPublicKey).mapValues { targetSnode in
|
||||
return getTargetSnodes(for: ourHexEncodedPubKey).mapValues { targetSnode in
|
||||
let lastHash = getLastMessageHashValue(for: targetSnode) ?? ""
|
||||
let parameters: [String:Any] = [ "pubKey" : hexEncodedPublicKey, "lastHash" : lastHash ]
|
||||
let parameters: [String:Any] = [ "pubKey" : ourHexEncodedPubKey, "lastHash" : lastHash ]
|
||||
return invoke(.getMessages, on: targetSnode, with: parameters).map { rawResponse in
|
||||
guard let json = rawResponse as? JSON, let rawMessages = json["messages"] as? [JSON] else { return [] }
|
||||
updateLastMessageHashValueIfPossible(for: targetSnode, from: rawMessages)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <SignalServiceKit/SignalServiceKit.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NS_SWIFT_NAME(LokiAddressMessage)
|
||||
@interface LKAddressMessage : TSOutgoingMessage
|
||||
|
||||
- (instancetype)initInThread:(nullable TSThread *)thread
|
||||
address:(NSString *)address
|
||||
port:(uint)port;
|
||||
|
||||
@property (nonatomic, readonly) NSString *address;
|
||||
@property (nonatomic, readonly) uint port;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,62 @@
|
|||
#import "LKAddressMessage.h"
|
||||
#import "NSDate+OWS.h"
|
||||
#import "SignalRecipient.h"
|
||||
#import <SignalServiceKit/SignalServiceKit-Swift.h>
|
||||
|
||||
@interface LKAddressMessage ()
|
||||
|
||||
@property (nonatomic) NSString *address;
|
||||
@property (nonatomic) uint port;
|
||||
|
||||
@end
|
||||
|
||||
@implementation LKAddressMessage
|
||||
|
||||
- (instancetype)initAddressMessageInThread:(nullable TSThread *)thread
|
||||
address:(NSString *)address
|
||||
port:(uint)port
|
||||
{
|
||||
self = [super initOutgoingMessageWithTimestamp:NSDate.ows_millisecondTimeStamp inThread:thread messageBody:nil attachmentIds:[NSMutableArray<NSString *> new]
|
||||
expiresInSeconds:0 expireStartedAt:0 isVoiceMessage:NO groupMetaMessage:TSGroupMetaMessageUnspecified quotedMessage:nil contactShare:nil linkPreview:nil];
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
_address = address;
|
||||
_port = port;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (SSKProtoContentBuilder *)contentBuilder:(SignalRecipient *)recipient {
|
||||
SSKProtoContentBuilder *contentBuilder = [super contentBuilder:recipient];
|
||||
|
||||
// Se
|
||||
SSKProtoLokiAddressMessageBuilder *addressBuilder = SSKProtoLokiAddressMessage.builder;
|
||||
[addressBuilder setPtpAddress:self.address];
|
||||
[addressBuilder setPtpPort:self.port];
|
||||
|
||||
NSError *error;
|
||||
SSKProtoLokiAddressMessage *addressMessage = [addressBuilder buildAndReturnError:&error];
|
||||
if (error || !addressMessage) {
|
||||
OWSFailDebug(@"Failed to build lokiAddressMessage for %@: %@", recipient.recipientId, error);
|
||||
} else {
|
||||
[contentBuilder setLokiAddressMessage:addressMessage];
|
||||
}
|
||||
|
||||
return contentBuilder;
|
||||
}
|
||||
|
||||
// We don't need to send any data message in this address message
|
||||
- (nullable SSKProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId {
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)shouldBeSaved { return false; }
|
||||
|
||||
- (uint)ttl {
|
||||
// Address messages should only last 1 minute
|
||||
return 1 * kMinuteInterval;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1500,6 +1500,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
if (existingFriendRequestMessage != nil && existingFriendRequestMessage.isFriendRequest) {
|
||||
[existingFriendRequestMessage saveFriendRequestStatus:TSMessageFriendRequestStatusAccepted withTransaction:transaction];
|
||||
}
|
||||
|
||||
// Send our p2p details to the other user
|
||||
LKAddressMessage *_Nullable onlineMessage = [LokiAPI onlineBroadcastMessageForThread:thread];
|
||||
if (onlineMessage != nil) {
|
||||
[self.messageSenderJobQueue addMessage:onlineMessage transaction:transaction];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue