Untie profile picture from auth token

This commit is contained in:
Niels Andriesse 2020-02-20 16:59:05 +11:00
parent bd7c62beb8
commit bf54d78b99
5 changed files with 56 additions and 37 deletions

View File

@ -5,7 +5,7 @@
<key>BuildDetails</key>
<dict>
<key>CarthageVersion</key>
<string>0.34.0</string>
<string>0.33.0</string>
<key>OSXVersion</key>
<string>10.15.3</string>
<key>WebRTCCommit</key>

View File

@ -770,6 +770,8 @@ static NSTimeInterval launchStartedAt;
[self.socketManager requestSocketOpen];
[Environment.shared.contactsManager fetchSystemContactsOnceIfAlreadyAuthorized];
NSString *userHexEncodedPublicKey = self.tsAccountManager.localNumber;
// Loki: Tell our friends that we are online
[LKP2PAPI broadcastOnlineStatus];
@ -777,7 +779,22 @@ static NSTimeInterval launchStartedAt;
[self startLongPollerIfNeeded];
// Loki: Get device links
[LKFileServerAPI getDeviceLinksAssociatedWith:self.tsAccountManager.localNumber];
[[LKFileServerAPI getDeviceLinksAssociatedWith:userHexEncodedPublicKey] retainUntilComplete];
// Loki: Update profile picture if needed
NSUserDefaults *userDefaults = NSUserDefaults.standardUserDefaults;
NSDate *now = [NSDate new];
NSDate *lastProfilePictureUpload = (NSDate *)[userDefaults objectForKey:@"lastProfilePictureUpload"];
if ([now timeIntervalSinceDate:lastProfilePictureUpload] > 14 * 24 * 60 * 60) {
OWSProfileManager *profileManager = OWSProfileManager.sharedManager;
NSString *displayName = [profileManager profileNameForRecipientId:userHexEncodedPublicKey];
UIImage *profilePicture = [profileManager profileAvatarForRecipientId:userHexEncodedPublicKey];
[profileManager updateLocalProfileName:displayName avatarImage:profilePicture success:^{
[userDefaults setObject:now forKey:@"lastProfilePictureUpload"];
} failure:^(NSError *error) {
// Do nothing
} requiresSync:YES];
}
if (![UIApplication sharedApplication].isRegisteredForRemoteNotifications) {
OWSLogInfo(@"Retrying to register for remote notifications since user hasn't registered yet.");
@ -1448,7 +1465,7 @@ static NSTimeInterval launchStartedAt;
[self startLongPollerIfNeeded];
// Loki: Get device links
[LKFileServerAPI getDeviceLinksAssociatedWith:self.tsAccountManager.localNumber];
[[LKFileServerAPI getDeviceLinksAssociatedWith:self.tsAccountManager.localNumber] retainUntilComplete]; // TODO: Is this even needed?
}
}

View File

@ -416,10 +416,10 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error);
NSData *encryptedAvatarData = [self encryptProfileData:avatarData profileKey:newProfileKey];
OWSAssertDebug(encryptedAvatarData.length > 0);
[[LKFileServerAPI setProfilePicture:encryptedAvatarData]
.thenOn(dispatch_get_main_queue(), ^(NSString *url) {
[[LKFileServerAPI uploadProfilePicture:encryptedAvatarData]
.thenOn(dispatch_get_main_queue(), ^(NSString *downloadURL) {
[self.localUserProfile updateWithProfileKey:newProfileKey dbConnection:self.dbConnection completion:^{
successBlock(url);
successBlock(downloadURL);
}];
})
.catchOn(dispatch_get_main_queue(), ^(id result) {

View File

@ -137,40 +137,33 @@ public final class LokiFileServerAPI : LokiDotNetAPI {
}
// MARK: Profile Pictures (Public API)
public static func setProfilePicture(_ profilePicture: Data) -> Promise<String> {
return Promise<String>() { seal in
guard profilePicture.count < maxFileSize else { return seal.reject(LokiDotNetAPIError.maxFileSizeExceeded) }
getAuthToken(for: server).done { token in
let url = "\(server)/users/me/avatar"
let parameters: JSON = [ "type" : attachmentType, "Content-Type" : "application/binary" ]
var error: NSError?
var request = AFHTTPRequestSerializer().multipartFormRequest(withMethod: "POST", urlString: url, parameters: parameters, constructingBodyWith: { formData in
formData.appendPart(withFileData: profilePicture, name: "avatar", fileName: UUID().uuidString, mimeType: "application/binary")
}, error: &error)
request.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
if let error = error {
print("[Loki] Couldn't upload profile picture due to error: \(error).")
throw error
}
let _ = LokiFileServerProxy(for: server).performLokiFileServerNSURLRequest(request as NSURLRequest).done { responseObject in
guard let json = responseObject as? JSON, let data = json["data"] as? JSON, let profilePicture = data["avatar_image"] as? JSON, let downloadURL = profilePicture["url"] as? String else {
print("[Loki] Couldn't parse profile picture from: \(responseObject).")
return seal.reject(LokiDotNetAPIError.parsingFailed)
}
return seal.fulfill(downloadURL)
}.catch { error in
seal.reject(error)
}
}.catch { error in
print("[Loki] Couldn't upload profile picture due to error: \(error).")
seal.reject(error)
public static func uploadProfilePicture(_ profilePicture: Data) -> Promise<String> {
guard profilePicture.count < maxFileSize else { return Promise(error: LokiDotNetAPIError.maxFileSizeExceeded) }
let url = "\(server)/files"
let parameters: JSON = [ "type" : attachmentType, "Content-Type" : "application/binary" ]
var error: NSError?
var request = AFHTTPRequestSerializer().multipartFormRequest(withMethod: "POST", urlString: url, parameters: parameters, constructingBodyWith: { formData in
formData.appendPart(withFileData: profilePicture, name: "content", fileName: UUID().uuidString, mimeType: "application/binary")
}, error: &error)
// Uploads to the Loki File Server shouldn't include any personally identifiable information so use a dummy auth token
request.addValue("Bearer loki", forHTTPHeaderField: "Authorization")
if let error = error {
print("[Loki] Couldn't upload profile picture due to error: \(error).")
return Promise(error: error)
}
return LokiFileServerProxy(for: server).performLokiFileServerNSURLRequest(request as NSURLRequest).map { responseObject in
guard let json = responseObject as? JSON, let data = json["data"] as? JSON, let downloadURL = data["url"] as? String else {
print("[Loki] Couldn't parse profile picture from: \(responseObject).")
throw LokiDotNetAPIError.parsingFailed
}
UserDefaults.standard[.lastProfilePictureUpload] = Date().timeIntervalSince1970
return downloadURL
}
}
// MARK: Profile Pictures (Public Obj-C API)
@objc(setProfilePicture:)
public static func objc_setProfilePicture(_ profilePicture: Data) -> AnyPromise {
return AnyPromise.from(setProfilePicture(profilePicture))
@objc(uploadProfilePicture:)
public static func objc_uploadProfilePicture(_ profilePicture: Data) -> AnyPromise {
return AnyPromise.from(uploadProfilePicture(profilePicture))
}
}

View File

@ -9,7 +9,11 @@ public enum LKUserDefaults {
/// Whether the device was unlinked as a slave device (used to notify the user on the landing screen).
case wasUnlinked
}
public enum Date : Swift.String {
case lastProfilePictureUpload
}
public enum Double : Swift.String {
case lastDeviceTokenUpload = "lastDeviceTokenUploadTime"
}
@ -36,6 +40,11 @@ public extension UserDefaults {
get { return self.bool(forKey: bool.rawValue) }
set { set(newValue, forKey: bool.rawValue) }
}
public subscript(date: LKUserDefaults.Date) -> Date? {
get { return self.object(forKey: date.rawValue) as? Date }
set { set(newValue, forKey: date.rawValue) }
}
public subscript(double: LKUserDefaults.Double) -> Double {
get { return self.double(forKey: double.rawValue) }