mirror of https://github.com/oxen-io/session-ios
parent
d48fd158b7
commit
a99fde4d3b
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||||
|
|
||||||
|
#import "TSYapDatabaseObject.h"
|
||||||
|
#import <Mantle/MTLJSONAdapter.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface OWSDevice : TSYapDatabaseObject <MTLJSONSerializing>
|
||||||
|
|
||||||
|
@property (nonatomic, readonly) NSInteger deviceId;
|
||||||
|
@property (nullable, nonatomic, readonly) NSString *name;
|
||||||
|
@property (nonatomic, readonly) NSDate *createdAt;
|
||||||
|
@property (nonatomic, readonly) NSDate *lastSeenAt;
|
||||||
|
|
||||||
|
+ (instancetype)deviceFromJSONDictionary:(NSDictionary *)deviceAttributes error:(NSError **)error;
|
||||||
|
+ (NSArray<OWSDevice *> *)secondaryDevices;
|
||||||
|
+ (void)replaceAll:(NSArray<OWSDevice *> *)devices;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,120 @@
|
|||||||
|
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||||
|
|
||||||
|
#import "OWSDevice.h"
|
||||||
|
#import "NSDate+millisecondTimeStamp.h"
|
||||||
|
#import "OWSError.h"
|
||||||
|
#import "YapDatabaseConnection.h"
|
||||||
|
#import "YapDatabaseTransaction.h"
|
||||||
|
#import <Mantle/MTLValueTransformer.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
static MTLValueTransformer *_millisecondTimestampToDateTransformer;
|
||||||
|
static int const OWSDevicePrimaryDeviceId = 1;
|
||||||
|
|
||||||
|
@implementation OWSDevice
|
||||||
|
|
||||||
|
@synthesize name = _name;
|
||||||
|
|
||||||
|
+ (instancetype)deviceFromJSONDictionary:(NSDictionary *)deviceAttributes error:(NSError **)error
|
||||||
|
{
|
||||||
|
return [MTLJSONAdapter modelOfClass:[self class] fromJSONDictionary:deviceAttributes error:error];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSDictionary *)JSONKeyPathsByPropertyKey
|
||||||
|
{
|
||||||
|
return @{
|
||||||
|
@"createdAt": @"created",
|
||||||
|
@"lastSeenAt": @"lastSeen",
|
||||||
|
@"deviceId": @"id",
|
||||||
|
@"name": @"name"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (MTLValueTransformer *)createdAtJSONTransformer
|
||||||
|
{
|
||||||
|
return self.millisecondTimestampToDateTransformer;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (MTLValueTransformer *)lastSeenAtJSONTransformer
|
||||||
|
{
|
||||||
|
return self.millisecondTimestampToDateTransformer;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)replaceAll:(NSArray<OWSDevice *> *)devices
|
||||||
|
{
|
||||||
|
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||||
|
[transaction removeAllObjectsInCollection:[self collection]];
|
||||||
|
for (OWSDevice *device in devices) {
|
||||||
|
[device saveWithTransaction:transaction];
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (MTLValueTransformer *)millisecondTimestampToDateTransformer
|
||||||
|
{
|
||||||
|
if (!_millisecondTimestampToDateTransformer) {
|
||||||
|
_millisecondTimestampToDateTransformer =
|
||||||
|
[MTLValueTransformer transformerUsingForwardBlock:^id(id value, BOOL *success, NSError **error) {
|
||||||
|
if ([value isKindOfClass:[NSNumber class]]) {
|
||||||
|
NSNumber *number = (NSNumber *)value;
|
||||||
|
NSDate *result = [NSDate ows_dateWithMillisecondsSince1970:[number longLongValue]];
|
||||||
|
if (result) {
|
||||||
|
*success = YES;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*success = NO;
|
||||||
|
*error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToDecodeJson,
|
||||||
|
[NSString stringWithFormat:@"unable to decode date from %@", value]);
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
reverseBlock:^id(id value, BOOL *success, NSError **error) {
|
||||||
|
if ([value isKindOfClass:[NSDate class]]) {
|
||||||
|
NSDate *date = (NSDate *)value;
|
||||||
|
NSNumber *result = [NSNumber numberWithLongLong:[NSDate ows_millisecondsSince1970ForDate:date]];
|
||||||
|
if (result) {
|
||||||
|
*success = YES;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*error = OWSErrorWithCodeDescription(OWSErrorCodeFailedToEncodeJson,
|
||||||
|
[NSString stringWithFormat:@"unable to encode date from %@", value]);
|
||||||
|
*success = NO;
|
||||||
|
return nil;
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
return _millisecondTimestampToDateTransformer;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSArray<OWSDevice *> *)secondaryDevices
|
||||||
|
{
|
||||||
|
NSMutableArray<OWSDevice *> *devices = [NSMutableArray new];
|
||||||
|
|
||||||
|
[self enumerateCollectionObjectsUsingBlock:^(id obj, BOOL *stop) {
|
||||||
|
if ([obj isKindOfClass:[OWSDevice class]]) {
|
||||||
|
OWSDevice *device = (OWSDevice *)obj;
|
||||||
|
if (device.deviceId != OWSDevicePrimaryDeviceId) {
|
||||||
|
[devices addObject:device];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
return [devices copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (nullable NSString *)name
|
||||||
|
{
|
||||||
|
if (_name) {
|
||||||
|
return _name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.deviceId == OWSDevicePrimaryDeviceId) {
|
||||||
|
return @"This Device";
|
||||||
|
}
|
||||||
|
return NSLocalizedString(@"UNNAMED_DEVICE", @"Label text in device manager for a device with no name");
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,18 @@
|
|||||||
|
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class OWSDevice;
|
||||||
|
|
||||||
|
@interface OWSDevicesService : NSObject
|
||||||
|
|
||||||
|
- (void)getDevicesWithSuccess:(void (^)(NSArray<OWSDevice *> *))successCallback
|
||||||
|
failure:(void (^)(NSError *))failureCallback;
|
||||||
|
|
||||||
|
- (void)unlinkDevice:(OWSDevice *)device
|
||||||
|
success:(void (^)())successCallback
|
||||||
|
failure:(void (^)(NSError *))failureCallback;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,84 @@
|
|||||||
|
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||||
|
|
||||||
|
#import "OWSDevicesService.h"
|
||||||
|
#import "OWSDeleteDeviceRequest.h"
|
||||||
|
#import "OWSDevice.h"
|
||||||
|
#import "OWSError.h"
|
||||||
|
#import "OWSGetDevicesRequest.h"
|
||||||
|
#import "TSNetworkManager.h"
|
||||||
|
#import <Mantle/MTLJSONAdapter.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@implementation OWSDevicesService
|
||||||
|
|
||||||
|
- (void)getDevicesWithSuccess:(void (^)(NSArray<OWSDevice *> *))successCallback
|
||||||
|
failure:(void (^)(NSError *))failureCallback
|
||||||
|
{
|
||||||
|
OWSGetDevicesRequest *request = [OWSGetDevicesRequest new];
|
||||||
|
[[TSNetworkManager sharedManager] makeRequest:request
|
||||||
|
success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||||
|
DDLogVerbose(@"Get devices request succeeded");
|
||||||
|
NSArray<OWSDevice *> *devices = [self parseResponse:responseObject];
|
||||||
|
|
||||||
|
if (devices) {
|
||||||
|
successCallback(devices);
|
||||||
|
} else {
|
||||||
|
failureCallback(OWSErrorWithCodeDescription(
|
||||||
|
OWSErrorCodeUnableToProcessServerResponse, @"Unable to parse server response"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||||
|
DDLogVerbose(@"Get devices request failed with error: %@", error);
|
||||||
|
failureCallback(error);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)unlinkDevice:(OWSDevice *)device
|
||||||
|
success:(void (^)())successCallback
|
||||||
|
failure:(void (^)(NSError *))failureCallback
|
||||||
|
{
|
||||||
|
OWSDeleteDeviceRequest *request = [[OWSDeleteDeviceRequest alloc] initWithDevice:device];
|
||||||
|
|
||||||
|
[[TSNetworkManager sharedManager] makeRequest:request
|
||||||
|
success:^(NSURLSessionDataTask *task, id responseObject) {
|
||||||
|
DDLogVerbose(@"Delete device request succeeded");
|
||||||
|
successCallback();
|
||||||
|
}
|
||||||
|
failure:^(NSURLSessionDataTask *task, NSError *error) {
|
||||||
|
DDLogVerbose(@"Get devices request failed with error: %@", error);
|
||||||
|
failureCallback(error);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray<OWSDevice *> *)parseResponse:(id)responseObject
|
||||||
|
{
|
||||||
|
if (![responseObject isKindOfClass:[NSDictionary class]]) {
|
||||||
|
DDLogError(@"Device response was not a dictionary.");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
NSDictionary *response = (NSDictionary *)responseObject;
|
||||||
|
|
||||||
|
NSArray<NSDictionary *> *devicesAttributes = response[@"devices"];
|
||||||
|
if (!devicesAttributes) {
|
||||||
|
DDLogError(@"Device response had no devices.");
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
NSMutableArray<OWSDevice *> *devices = [NSMutableArray new];
|
||||||
|
for (NSDictionary *deviceAttributes in devicesAttributes) {
|
||||||
|
NSError *error;
|
||||||
|
OWSDevice *device = [OWSDevice deviceFromJSONDictionary:deviceAttributes error:&error];
|
||||||
|
if (error) {
|
||||||
|
DDLogError(@"Failed to build device from dictionary with error: %@", error);
|
||||||
|
} else {
|
||||||
|
[devices addObject:device];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return [devices copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||||
|
|
||||||
|
#import "TSRequest.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class OWSDevice;
|
||||||
|
|
||||||
|
@interface OWSDeleteDeviceRequest : TSRequest
|
||||||
|
|
||||||
|
- (instancetype)initWithDevice:(OWSDevice *)device;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,27 @@
|
|||||||
|
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||||
|
|
||||||
|
#import "OWSDeleteDeviceRequest.h"
|
||||||
|
#import "OWSDevice.h"
|
||||||
|
#import "TSConstants.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@implementation OWSDeleteDeviceRequest
|
||||||
|
|
||||||
|
- (instancetype)initWithDevice:(OWSDevice *)device
|
||||||
|
{
|
||||||
|
NSString *deleteDevicePath = [NSString
|
||||||
|
stringWithFormat:textSecureDevicesAPIFormat, [NSString stringWithFormat:@"%ld", (long)device.deviceId]];
|
||||||
|
self = [super initWithURL:[NSURL URLWithString:deleteDevicePath]];
|
||||||
|
if (!self) {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self setHTTPMethod:@"DELETE"];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||||
|
|
||||||
|
#import "TSRequest.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface OWSGetDevicesRequest : TSRequest
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||||
|
|
||||||
|
#import "OWSGetDevicesRequest.h"
|
||||||
|
#import "TSConstants.h"
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@implementation OWSGetDevicesRequest
|
||||||
|
|
||||||
|
- (instancetype)init
|
||||||
|
{
|
||||||
|
NSString *getDevicesPath = [NSString stringWithFormat:textSecureDevicesAPIFormat, @""];
|
||||||
|
self = [super initWithURL:[NSURL URLWithString:getDevicesPath]];
|
||||||
|
if (!self) {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
[self setHTTPMethod:@"GET"];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
@ -1,13 +1,11 @@
|
|||||||
//
|
|
||||||
// NSDate+millisecondTimeStamp.h
|
|
||||||
// Signal
|
|
||||||
//
|
|
||||||
// Created by Frederic Jacobs on 25/11/14.
|
// Created by Frederic Jacobs on 25/11/14.
|
||||||
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||||
//
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
@interface NSDate (millisecondTimeStamp)
|
@interface NSDate (millisecondTimeStamp)
|
||||||
|
|
||||||
+ (uint64_t)ows_millisecondTimeStamp;
|
+ (uint64_t)ows_millisecondTimeStamp;
|
||||||
|
+ (NSDate *)ows_dateWithMillisecondsSince1970:(uint64_t)milliseconds;
|
||||||
|
+ (uint64_t)ows_millisecondsSince1970ForDate:(NSDate *)date;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
Loading…
Reference in New Issue