Add Notification Service Extension, decrypt push notifications, modify push notification alerts.

Signed-off-by: Ivan Sein <ivan@nextcloud.com>
This commit is contained in:
Ivan Sein 2017-11-20 17:24:26 +01:00
Родитель 7c7a691e8d
Коммит 527ba2232c
11 изменённых файлов: 466 добавлений и 33 удалений

Просмотреть файл

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>NotificationServiceExtension</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.usernotifications.service</string>
<key>NSExtensionPrincipalClass</key>
<string>NotificationService</string>
</dict>
</dict>
</plist>

Просмотреть файл

@ -0,0 +1,13 @@
//
// NotificationService.h
// NotificationServiceExtension
//
// Created by Ivan Sein on 14.11.17.
// Copyright © 2017 struktur AG. All rights reserved.
//
#import <UserNotifications/UserNotifications.h>
@interface NotificationService : UNNotificationServiceExtension
@end

Просмотреть файл

@ -0,0 +1,67 @@
//
// NotificationService.m
// NotificationServiceExtension
//
// Created by Ivan Sein on 14.11.17.
// Copyright © 2017 struktur AG. All rights reserved.
//
#import "NotificationService.h"
#import "UICKeyChainStore.h"
#import "NCSettingsController.h"
@interface NotificationService ()
@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@end
@implementation NotificationService
- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
self.contentHandler = contentHandler;
self.bestAttemptContent = [request.content mutableCopy];
self.bestAttemptContent.title = @"Nextcloud notification 🔔";
self.bestAttemptContent.body = @"";
NSString *message = [self.bestAttemptContent.userInfo objectForKey:@"subject"];
NSString *decryptedMessage = nil;
@try {
UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.nextcloud.Talk"
accessGroup:@"group.com.nextcloud.Talk"];
decryptedMessage = [[NCSettingsController sharedInstance] decryptPushNotification:message
withDevicePrivateKey:[keychain dataForKey:kNCPNPrivateKey]];
} @catch (NSException *exception) {
NSLog(@"An error ocurred decrypting the message. %@", exception);
}
if (decryptedMessage) {
NSData *data = [decryptedMessage dataUsingEncoding:NSUTF8StringEncoding];
id messageJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
decryptedMessage = [messageJSON objectForKey:@"subject"];
self.bestAttemptContent.body = decryptedMessage;
NSString *appId = [messageJSON objectForKey:@"app"];
if ([appId isEqualToString:@"spreed"]) {
self.bestAttemptContent.title = @"Talk notification 📞";
}
}
self.contentHandler(self.bestAttemptContent);
}
- (void)serviceExtensionTimeWillExpire {
// Called just before the extension will be terminated by the system.
// Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
self.bestAttemptContent.title = @"Nextcloud notification 🔔";
self.bestAttemptContent.body = @"";
self.contentHandler(self.bestAttemptContent);
}
@end

Просмотреть файл

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.nextcloud.Talk</string>
</array>
</dict>
</plist>

Просмотреть файл

@ -1,10 +1,15 @@
source 'https://github.com/CocoaPods/Specs.git'
target "VideoCalls" do
platform :ios, '9.0'
target "VideoCalls" do
pod 'AFNetworking', '~> 2.5'
pod 'DateTools'
pod 'GoogleWebRTC'
pod 'Firebase/Core'
pod 'Firebase/Messaging'
end
target "NotificationServiceExtension" do
pod 'AFNetworking', '~> 2.5'
end

Просмотреть файл

@ -14,6 +14,15 @@
2C0574A41EDDA2E300D9E7F2 /* LoginViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C0574A21EDDA2E300D9E7F2 /* LoginViewController.m */; };
2C0574A51EDDA2E300D9E7F2 /* LoginViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2C0574A31EDDA2E300D9E7F2 /* LoginViewController.xib */; };
2C2E64251F3462AF00D39CE8 /* NCSignalingMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C2E64241F3462AF00D39CE8 /* NCSignalingMessage.m */; };
2C3F6AA81FBB1ACD00E2705C /* NotificationService.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C3F6AA71FBB1ACD00E2705C /* NotificationService.m */; };
2C3F6AAC1FBB1ACD00E2705C /* NotificationServiceExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 2C3F6AA41FBB1ACC00E2705C /* NotificationServiceExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
2C3F6AB31FBB45E600E2705C /* NCSettingsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA1CC941F014EF9002FE6A2 /* NCSettingsController.m */; };
2C3F6AB41FBB45FD00E2705C /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C8B60131FB4A9DA006E87EF /* libcrypto.a */; };
2C3F6AB51FBB460100E2705C /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C8B60141FB4A9DA006E87EF /* libssl.a */; };
2C3F6AB61FBB47B800E2705C /* NCAPIController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA1CCA91F02D1A4002FE6A2 /* NCAPIController.m */; };
2C3F6AB71FBB47C400E2705C /* UICKeyChainStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA1CC991F0161EA002FE6A2 /* UICKeyChainStore.m */; };
2C3F6AB81FBB4C9500E2705C /* NCRoom.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA1CCC21F166CC5002FE6A2 /* NCRoom.m */; };
2C3F6AB91FBB4C9D00E2705C /* NCUser.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA1CCCC1F181741002FE6A2 /* NCUser.m */; };
2C4D7D631F2F7C2C00FF4A0D /* ARDCaptureController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D7D621F2F7C2C00FF4A0D /* ARDCaptureController.m */; };
2C4D7D691F2F7DBC00FF4A0D /* ARDSettingsModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D7D651F2F7DBC00FF4A0D /* ARDSettingsModel.m */; };
2C4D7D6A1F2F7DBC00FF4A0D /* ARDSettingsStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 2C4D7D681F2F7DBC00FF4A0D /* ARDSettingsStore.m */; };
@ -54,9 +63,34 @@
2CA1CCDB1F1F6FCA002FE6A2 /* RoomTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 2CA1CCD91F1F6FCA002FE6A2 /* RoomTableViewCell.m */; };
2CB5D0531FB4D1FD00D7A5B7 /* libssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C8B60141FB4A9DA006E87EF /* libssl.a */; };
2CB5D0541FB4D20B00D7A5B7 /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2C8B60131FB4A9DA006E87EF /* libcrypto.a */; };
85032FFE8557E8F29A3C79B8 /* libPods-NotificationServiceExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 49EC325ACC97A400B9FAFA27 /* libPods-NotificationServiceExtension.a */; };
DB6A892B5CEBD4812F7C52EF /* libPods-VideoCalls.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6267808DF11BEB859C0BE9F1 /* libPods-VideoCalls.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
2C3F6AAA1FBB1ACD00E2705C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2C0574751EDD9E8E00D9E7F2 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 2C3F6AA31FBB1ACC00E2705C;
remoteInfo = NotificationServiceExtension;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
2C3F6AB01FBB1ACD00E2705C /* Embed App Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
2C3F6AAC1FBB1ACD00E2705C /* NotificationServiceExtension.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
2C05747D1EDD9E8E00D9E7F2 /* VideoCalls.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VideoCalls.app; sourceTree = BUILT_PRODUCTS_DIR; };
2C0574811EDD9E8E00D9E7F2 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
@ -70,6 +104,10 @@
2C0574A31EDDA2E300D9E7F2 /* LoginViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LoginViewController.xib; sourceTree = "<group>"; };
2C2E64231F3462AF00D39CE8 /* NCSignalingMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NCSignalingMessage.h; sourceTree = "<group>"; };
2C2E64241F3462AF00D39CE8 /* NCSignalingMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NCSignalingMessage.m; sourceTree = "<group>"; };
2C3F6AA41FBB1ACC00E2705C /* NotificationServiceExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotificationServiceExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
2C3F6AA61FBB1ACD00E2705C /* NotificationService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NotificationService.h; sourceTree = "<group>"; };
2C3F6AA71FBB1ACD00E2705C /* NotificationService.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationService.m; sourceTree = "<group>"; };
2C3F6AA91FBB1ACD00E2705C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
2C4D7D611F2F7C2C00FF4A0D /* ARDCaptureController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARDCaptureController.h; sourceTree = "<group>"; };
2C4D7D621F2F7C2C00FF4A0D /* ARDCaptureController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARDCaptureController.m; sourceTree = "<group>"; };
2C4D7D641F2F7DBC00FF4A0D /* ARDSettingsModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARDSettingsModel.h; sourceTree = "<group>"; };
@ -212,7 +250,11 @@
2CA1CCD51F1E664C002FE6A2 /* ContactsTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ContactsTableViewCell.xib; sourceTree = "<group>"; };
2CA1CCD81F1F6FCA002FE6A2 /* RoomTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RoomTableViewCell.h; sourceTree = "<group>"; };
2CA1CCD91F1F6FCA002FE6A2 /* RoomTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RoomTableViewCell.m; sourceTree = "<group>"; };
2CF6F5E21FC211EC00E4EFAA /* NotificationServiceExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NotificationServiceExtension.entitlements; sourceTree = "<group>"; };
49EC325ACC97A400B9FAFA27 /* libPods-NotificationServiceExtension.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-NotificationServiceExtension.a"; sourceTree = BUILT_PRODUCTS_DIR; };
5EF849CBD848BB3194C0D885 /* Pods-NotificationServiceExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationServiceExtension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.debug.xcconfig"; sourceTree = "<group>"; };
6267808DF11BEB859C0BE9F1 /* libPods-VideoCalls.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-VideoCalls.a"; sourceTree = BUILT_PRODUCTS_DIR; };
73D489B0CDBE660CF768BABE /* Pods-NotificationServiceExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationServiceExtension.release.xcconfig"; path = "Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension.release.xcconfig"; sourceTree = "<group>"; };
8BD08DF13BF3479DEEECFEB1 /* Pods-VideoCalls.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VideoCalls.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VideoCalls/Pods-VideoCalls.debug.xcconfig"; sourceTree = "<group>"; };
E8DF4DF89BBD55A5ED6488CB /* Pods-VideoCalls.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VideoCalls.release.xcconfig"; path = "Pods/Target Support Files/Pods-VideoCalls/Pods-VideoCalls.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -234,12 +276,23 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
2C3F6AA11FBB1ACC00E2705C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2C3F6AB51FBB460100E2705C /* libssl.a in Frameworks */,
2C3F6AB41FBB45FD00E2705C /* libcrypto.a in Frameworks */,
85032FFE8557E8F29A3C79B8 /* libPods-NotificationServiceExtension.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
2C0574741EDD9E8E00D9E7F2 = {
isa = PBXGroup;
children = (
2C3F6AA51FBB1ACC00E2705C /* NotificationServiceExtension */,
2C05747E1EDD9E8E00D9E7F2 /* Products */,
2C05749C1EDDA01700D9E7F2 /* ThirdParty */,
2C05747F1EDD9E8E00D9E7F2 /* VideoCalls */,
@ -252,6 +305,7 @@
isa = PBXGroup;
children = (
2C05747D1EDD9E8E00D9E7F2 /* VideoCalls.app */,
2C3F6AA41FBB1ACC00E2705C /* NotificationServiceExtension.appex */,
);
name = Products;
sourceTree = "<group>";
@ -298,6 +352,17 @@
name = ThirdParty;
sourceTree = "<group>";
};
2C3F6AA51FBB1ACC00E2705C /* NotificationServiceExtension */ = {
isa = PBXGroup;
children = (
2CF6F5E21FC211EC00E4EFAA /* NotificationServiceExtension.entitlements */,
2C3F6AA61FBB1ACD00E2705C /* NotificationService.h */,
2C3F6AA71FBB1ACD00E2705C /* NotificationService.m */,
2C3F6AA91FBB1ACD00E2705C /* Info.plist */,
);
path = NotificationServiceExtension;
sourceTree = "<group>";
};
2C4D7D601F2F7C2C00FF4A0D /* AppRTC */ = {
isa = PBXGroup;
children = (
@ -507,6 +572,7 @@
2C90E5661EDDE1340093D85A /* CoreGraphics.framework */,
2C90E5631EDDE0FB0093D85A /* Foundation.framework */,
6267808DF11BEB859C0BE9F1 /* libPods-VideoCalls.a */,
49EC325ACC97A400B9FAFA27 /* libPods-NotificationServiceExtension.a */,
);
name = Frameworks;
sourceTree = "<group>";
@ -535,6 +601,8 @@
children = (
8BD08DF13BF3479DEEECFEB1 /* Pods-VideoCalls.debug.xcconfig */,
E8DF4DF89BBD55A5ED6488CB /* Pods-VideoCalls.release.xcconfig */,
5EF849CBD848BB3194C0D885 /* Pods-NotificationServiceExtension.debug.xcconfig */,
73D489B0CDBE660CF768BABE /* Pods-NotificationServiceExtension.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
@ -553,16 +621,37 @@
29696B57B26EBF9C28436CE8 /* [CP] Embed Pods Frameworks */,
A3C686B1B84C4462F93441AB /* [CP] Copy Pods Resources */,
2C8035721F950BA800501B5C /* ShellScript */,
2C3F6AB01FBB1ACD00E2705C /* Embed App Extensions */,
);
buildRules = (
);
dependencies = (
2C3F6AAB1FBB1ACD00E2705C /* PBXTargetDependency */,
);
name = VideoCalls;
productName = VideoCalls;
productReference = 2C05747D1EDD9E8E00D9E7F2 /* VideoCalls.app */;
productType = "com.apple.product-type.application";
};
2C3F6AA31FBB1ACC00E2705C /* NotificationServiceExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2C3F6AAF1FBB1ACD00E2705C /* Build configuration list for PBXNativeTarget "NotificationServiceExtension" */;
buildPhases = (
BD6E17ECE1FB7C457F620E30 /* [CP] Check Pods Manifest.lock */,
2C3F6AA01FBB1ACC00E2705C /* Sources */,
2C3F6AA11FBB1ACC00E2705C /* Frameworks */,
2C3F6AA21FBB1ACC00E2705C /* Resources */,
93097A6DB9AF5BB051C5E3E9 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = NotificationServiceExtension;
productName = NotificationServiceExtension;
productReference = 2C3F6AA41FBB1ACC00E2705C /* NotificationServiceExtension.appex */;
productType = "com.apple.product-type.app-extension";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@ -577,14 +666,33 @@
DevelopmentTeam = NKUJUXUJ3B;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.ApplicationGroups.iOS = {
enabled = 1;
};
com.apple.BackgroundModes = {
enabled = 1;
};
com.apple.Keychain = {
enabled = 0;
};
com.apple.Push = {
enabled = 1;
};
};
};
2C3F6AA31FBB1ACC00E2705C = {
CreatedOnToolsVersion = 9.0.1;
DevelopmentTeam = NKUJUXUJ3B;
ProvisioningStyle = Automatic;
SystemCapabilities = {
com.apple.ApplicationGroups.iOS = {
enabled = 1;
};
com.apple.Keychain = {
enabled = 0;
};
};
};
};
};
buildConfigurationList = 2C0574781EDD9E8E00D9E7F2 /* Build configuration list for PBXProject "VideoCalls" */;
@ -601,6 +709,7 @@
projectRoot = "";
targets = (
2C05747C1EDD9E8E00D9E7F2 /* VideoCalls */,
2C3F6AA31FBB1ACC00E2705C /* NotificationServiceExtension */,
);
};
/* End PBXProject section */
@ -621,6 +730,13 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
2C3F6AA21FBB1ACC00E2705C /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@ -673,6 +789,21 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
93097A6DB9AF5BB051C5E3E9 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "[CP] Copy Pods Resources";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-NotificationServiceExtension/Pods-NotificationServiceExtension-resources.sh\"\n";
showEnvVarsInLog = 0;
};
A3C686B1B84C4462F93441AB /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@ -691,6 +822,24 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-VideoCalls/Pods-VideoCalls-resources.sh\"\n";
showEnvVarsInLog = 0;
};
BD6E17ECE1FB7C457F620E30 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-NotificationServiceExtension-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@ -732,8 +881,29 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
2C3F6AA01FBB1ACC00E2705C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2C3F6AB61FBB47B800E2705C /* NCAPIController.m in Sources */,
2C3F6AB91FBB4C9D00E2705C /* NCUser.m in Sources */,
2C3F6AA81FBB1ACD00E2705C /* NotificationService.m in Sources */,
2C3F6AB31FBB45E600E2705C /* NCSettingsController.m in Sources */,
2C3F6AB71FBB47C400E2705C /* UICKeyChainStore.m in Sources */,
2C3F6AB81FBB4C9500E2705C /* NCRoom.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
2C3F6AAB1FBB1ACD00E2705C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 2C3F6AA31FBB1ACC00E2705C /* NotificationServiceExtension */;
targetProxy = 2C3F6AAA1FBB1ACD00E2705C /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
2C05748C1EDD9E8E00D9E7F2 /* Main.storyboard */ = {
isa = PBXVariantGroup;
@ -932,6 +1102,80 @@
};
name = Release;
};
2C3F6AAD1FBB1ACD00E2705C /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 5EF849CBD848BB3194C0D885 /* Pods-NotificationServiceExtension.debug.xcconfig */;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = NotificationServiceExtension/NotificationServiceExtension.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = NKUJUXUJ3B;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
GCC_C_LANGUAGE_STANDARD = c11;
HEADER_SEARCH_PATHS = (
"$(inherited)",
"\"$(PROJECT_DIR)/ThirdParty\"/**",
);
INFOPLIST_FILE = NotificationServiceExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/ThirdParty/openssl",
);
PRODUCT_BUNDLE_IDENTIFIER = com.nextcloud.Talk.NotificationServiceExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
2C3F6AAE1FBB1ACD00E2705C /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 73D489B0CDBE660CF768BABE /* Pods-NotificationServiceExtension.release.xcconfig */;
buildSettings = {
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_ENTITLEMENTS = NotificationServiceExtension/NotificationServiceExtension.entitlements;
CODE_SIGN_IDENTITY = "iPhone Distribution: Nextcloud GmbH (NKUJUXUJ3B)";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = NKUJUXUJ3B;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
GCC_C_LANGUAGE_STANDARD = c11;
HEADER_SEARCH_PATHS = (
"$(inherited)",
"\"$(PROJECT_DIR)/ThirdParty\"/**",
);
INFOPLIST_FILE = NotificationServiceExtension/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/ThirdParty/openssl",
);
PRODUCT_BUNDLE_IDENTIFIER = com.nextcloud.Talk.NotificationServiceExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@ -953,6 +1197,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2C3F6AAF1FBB1ACD00E2705C /* Build configuration list for PBXNativeTarget "NotificationServiceExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2C3F6AAD1FBB1ACD00E2705C /* Debug */,
2C3F6AAE1FBB1ACD00E2705C /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 2C0574751EDD9E8E00D9E7F2 /* Project object */;

Просмотреть файл

@ -63,7 +63,6 @@
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
@ -101,7 +100,9 @@
{
NSLog(@"FCM registration token: %@", fcmToken);
[NCSettingsController sharedInstance].ncPushToken = fcmToken;
[UICKeyChainStore setString:fcmToken forKey:kNCPushTokenKey];
UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.nextcloud.Talk"
accessGroup:@"group.com.nextcloud.Talk"];
[keychain setString:fcmToken forKey:kNCPushTokenKey];
}

Просмотреть файл

@ -98,9 +98,12 @@ NSString * const NCLoginCompletedNotification = @"NCLoginCompletedNotification
[NCSettingsController sharedInstance].ncUser = user;
[NCSettingsController sharedInstance].ncToken = token;
[UICKeyChainStore setString:_serverUrl forKey:kNCServerKey];
[UICKeyChainStore setString:user forKey:kNCUserKey];
[UICKeyChainStore setString:token forKey:kNCTokenKey];
UICKeyChainStore *keychain = [UICKeyChainStore keyChainStoreWithService:@"com.nextcloud.Talk"
accessGroup:@"group.com.nextcloud.Talk"];
[keychain setString:_serverUrl forKey:kNCServerKey];
[keychain setString:user forKey:kNCUserKey];
[keychain setString:token forKey:kNCTokenKey];
[[NCAPIController sharedInstance] setNCServer:_serverUrl];
[[NCAPIController sharedInstance] setAuthHeaderWithUser:user andToken:token];
@ -112,7 +115,7 @@ NSString * const NCLoginCompletedNotification = @"NCLoginCompletedNotification
if (!error) {
NSString *userDisplayName = [userProfile objectForKey:@"displayname"];
[NCSettingsController sharedInstance].ncUserDisplayName = userDisplayName;
[UICKeyChainStore setString:userDisplayName forKey:kNCUserDisplayNameKey];
[keychain setString:userDisplayName forKey:kNCUserDisplayNameKey];
} else {
NSLog(@"Error while getting the user profile");
}
@ -131,9 +134,9 @@ NSString * const NCLoginCompletedNotification = @"NCLoginCompletedNotification
[NCSettingsController sharedInstance].ncDeviceIdentifier = deviceIdentifier;
[NCSettingsController sharedInstance].ncDeviceSignature = signature;
[UICKeyChainStore setString:publicKey forKey:kNCUserPublicKey];
[UICKeyChainStore setString:deviceIdentifier forKey:kNCDeviceIdentifier];
[UICKeyChainStore setString:signature forKey:kNCDeviceSignature];
[keychain setString:publicKey forKey:kNCUserPublicKey];
[keychain setString:deviceIdentifier forKey:kNCDeviceIdentifier];
[keychain setString:signature forKey:kNCDeviceSignature];
[[NCAPIController sharedInstance] subscribeToPushServer:^(NSError *error, NSInteger errorCode) {
if (!error) {

Просмотреть файл

@ -41,5 +41,6 @@ extern NSString * const kNCUserPublicKey;
- (void)cleanUserAndServerStoredValues;
- (BOOL)generatePushNotificationsKeyPair;
- (NSString *)pushTokenSHA512;
- (NSString *)decryptPushNotification:(NSString *)message withDevicePrivateKey:(NSData *)privateKey;
@end

Просмотреть файл

@ -13,10 +13,17 @@
#import <openssl/bio.h>
#import <openssl/bn.h>
#import <openssl/sha.h>
#import <openssl/err.h>
#import <CommonCrypto/CommonDigest.h>
#import "NCAPIController.h"
@interface NCSettingsController ()
{
UICKeyChainStore *_keychain;
}
@end
@implementation NCSettingsController
NSString * const kNCServerKey = @"ncServer";
@ -45,6 +52,8 @@ NSString * const kNCUserPublicKey = @"ncUserPublicKey";
{
self = [super init];
if (self) {
_keychain = [UICKeyChainStore keyChainStoreWithService:@"com.nextcloud.Talk"
accessGroup:@"group.com.nextcloud.Talk"];
[self readValuesFromKeyChain];
}
return self;
@ -54,16 +63,16 @@ NSString * const kNCUserPublicKey = @"ncUserPublicKey";
- (void)readValuesFromKeyChain
{
_ncServer = [UICKeyChainStore stringForKey:kNCServerKey];
_ncUser = [UICKeyChainStore stringForKey:kNCUserKey];
_ncUserDisplayName = [UICKeyChainStore stringForKey:kNCUserDisplayNameKey];
_ncToken = [UICKeyChainStore stringForKey:kNCTokenKey];
_ncPushToken = [UICKeyChainStore stringForKey:kNCPushTokenKey];
_ncPNPublicKey = [UICKeyChainStore dataForKey:kNCPNPublicKey];
_ncPNPrivateKey = [UICKeyChainStore dataForKey:kNCPNPrivateKey];
_ncDeviceIdentifier = [UICKeyChainStore stringForKey:kNCDeviceIdentifier];
_ncDeviceSignature = [UICKeyChainStore stringForKey:kNCDeviceSignature];
_ncUserPublicKey = [UICKeyChainStore stringForKey:kNCUserPublicKey];
_ncServer = [_keychain stringForKey:kNCServerKey];
_ncUser = [_keychain stringForKey:kNCUserKey];
_ncUserDisplayName = [_keychain stringForKey:kNCUserDisplayNameKey];
_ncToken = [_keychain stringForKey:kNCTokenKey];
_ncPushToken = [_keychain stringForKey:kNCPushTokenKey];
_ncPNPublicKey = [_keychain dataForKey:kNCPNPublicKey];
_ncPNPrivateKey = [_keychain dataForKey:kNCPNPrivateKey];
_ncDeviceIdentifier = [_keychain stringForKey:kNCDeviceIdentifier];
_ncDeviceSignature = [_keychain stringForKey:kNCDeviceSignature];
_ncUserPublicKey = [_keychain stringForKey:kNCUserPublicKey];
}
- (void)cleanUserAndServerStoredValues
@ -78,15 +87,15 @@ NSString * const kNCUserPublicKey = @"ncUserPublicKey";
_ncDeviceIdentifier = nil;
_ncDeviceSignature = nil;
[UICKeyChainStore removeItemForKey:kNCServerKey];
[UICKeyChainStore removeItemForKey:kNCUserKey];
[UICKeyChainStore removeItemForKey:kNCUserDisplayNameKey];
[UICKeyChainStore removeItemForKey:kNCTokenKey];
[UICKeyChainStore removeItemForKey:kNCPNPublicKey];
[UICKeyChainStore removeItemForKey:kNCPNPrivateKey];
[UICKeyChainStore removeItemForKey:kNCDeviceIdentifier];
[UICKeyChainStore removeItemForKey:kNCDeviceSignature];
[UICKeyChainStore removeItemForKey:kNCUserPublicKey];
[_keychain removeItemForKey:kNCServerKey];
[_keychain removeItemForKey:kNCUserKey];
[_keychain removeItemForKey:kNCUserDisplayNameKey];
[_keychain removeItemForKey:kNCTokenKey];
[_keychain removeItemForKey:kNCPNPublicKey];
[_keychain removeItemForKey:kNCPNPrivateKey];
[_keychain removeItemForKey:kNCDeviceIdentifier];
[_keychain removeItemForKey:kNCDeviceSignature];
[_keychain removeItemForKey:kNCUserPublicKey];
#warning TODO - Restore NCAPIController in a diferent way
[[NCAPIController sharedInstance] setAuthHeaderWithUser:NULL andToken:NULL];
@ -116,7 +125,7 @@ NSString * const kNCUserPublicKey = @"ncUserPublicKey";
BIO_read(publicKeyBIO, keyBytes, len);
_ncPNPublicKey = [NSData dataWithBytes:keyBytes length:len];
[UICKeyChainStore setData:_ncPNPublicKey forKey:kNCPNPublicKey];
[_keychain setData:_ncPNPublicKey forKey:kNCPNPublicKey];
NSLog(@"Push Notifications Key Pair generated: \n%@", [[NSString alloc] initWithData:_ncPNPublicKey encoding:NSUTF8StringEncoding]);
// PrivateKey
@ -128,7 +137,7 @@ NSString * const kNCUserPublicKey = @"ncUserPublicKey";
BIO_read(privateKeyBIO, keyBytes, len);
_ncPNPrivateKey = [NSData dataWithBytes:keyBytes length:len];
[UICKeyChainStore setData:_ncPNPrivateKey forKey:kNCPNPrivateKey];
[_keychain setData:_ncPNPrivateKey forKey:kNCPNPrivateKey];
EVP_PKEY_free(pkey);
@ -165,6 +174,42 @@ cleanup:
return pkey;
}
- (NSString *)decryptPushNotification:(NSString *)message withDevicePrivateKey:(NSData *)privateKey
{
NSString *privateKeyString = [[NSString alloc] initWithData:privateKey encoding:NSUTF8StringEncoding];
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:message options:0];
char *privKey = (char *)[privateKeyString UTF8String];
// Get Device Private Key from PEM
BIO *bio = BIO_new(BIO_s_mem());
BIO_write(bio, privKey, (int)strlen(privKey));
EVP_PKEY* pkey = 0;
PEM_read_bio_PrivateKey(bio, &pkey, 0, 0);
RSA* rsa = EVP_PKEY_get1_RSA(pkey);
// Decrypt the message
unsigned char *decrypted = (unsigned char *) malloc(4096);
int decrypted_length = RSA_private_decrypt((int)[decodedData length], [decodedData bytes], decrypted, rsa, RSA_PKCS1_PADDING);
if(decrypted_length == -1) {
char buffer[500];
ERR_error_string(ERR_get_error(), buffer);
NSLog(@"%@",[NSString stringWithUTF8String:buffer]);
return nil;
}
NSString *decryptString = [[NSString alloc] initWithBytes:decrypted length:decrypted_length encoding:NSUTF8StringEncoding];
if (decrypted)
free(decrypted);
free(bio);
free(rsa);
return decryptString;
}
- (NSString *)pushTokenSHA512
{
return [self createSHA512:_ncPushToken];

Просмотреть файл

@ -4,5 +4,9 @@
<dict>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.nextcloud.Talk</string>
</array>
</dict>
</plist>