Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions Privitty.framework/Headers/Privitty.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,77 @@ FOUNDATION_EXPORT const unsigned char PrivittyVersionString[];

- (nullable NSDictionary*)getConfigWithKey:(NSString*)key;

// =============================================================================
// FORWARD ACCESS CONTROL (Three-party Trust Model)
// =============================================================================

/**
* Forward peer add request - Add a forwardee to forward file access
* @param chatId Chat identifier with the relay/owner
* @param forwardeeChatId Chat identifier with the forwardee
* @param prvFile Path to the .prv file to forward
* @return Result dictionary with PDU (nullable on error)
*/
- (nullable NSDictionary*)processInitForwardPeerAddRequestWithChatId:(NSString*)chatId
forwardeeChatId:(NSString*)forwardeeChatId
prvFile:(NSString*)prvFile;

/**
* Forwardee initiates forward access request - Request access to a forwarded file
* @param chatId Chat identifier with the relay
* @param filePath Path to the .prv file
* @return Result dictionary with PDU (nullable on error)
*/
- (nullable NSDictionary*)processInitForwardAccessRequestWithChatId:(NSString*)chatId
filePath:(NSString*)filePath;

/**
* Original owner accepts relay forward access request
* @param chatId Chat identifier with the relay
* @param filePath Path to the .prv file
* @param contactId ID of the forwarder/contact requesting access
* @param accessDuration Duration in seconds for access validity (0 for unlimited)
* @param allowDownload Whether to allow download of the file
* @return Result dictionary with PDU (nullable on error)
*/
- (nullable NSDictionary*)processInitRevertRelayForwardAccessAcceptWithChatId:(NSString*)chatId
filePath:(NSString*)filePath
contactId:(NSString*)contactId
accessDuration:(NSInteger)accessDuration
allowDownload:(BOOL)allowDownload;

/**
* Original owner denies relay forward access request
* @param chatId Chat identifier with the relay
* @param filePath Path to the .prv file
* @param contactId ID of the forwarder/contact requesting access
* @param denialReason Optional reason for denial (can be nil)
* @return Result dictionary with PDU (nullable on error)
*/
- (nullable NSDictionary*)processInitRevertRelayForwardAccessDeniedWithChatId:(NSString*)chatId
filePath:(NSString*)filePath
contactId:(NSString*)contactId
denialReason:(nullable NSString*)denialReason;

/**
* Decrypt a forwarded file (file that was forwarded from another peer)
* @param fileId File identifier (actually the prv_file path)
* @param forwarderPeer Peer who forwarded the file (actually the chat_id)
* @return Result dictionary with decryption result (nullable on error)
*/
- (nullable NSDictionary*)processForwardedFileDecryptRequestWithFileId:(NSString*)fileId
forwarderPeer:(NSString*)forwarderPeer;

/**
* Get detailed file access status list with owner, shared, and forwarded information
* Returns comprehensive view of the file's access control chain in three-party trust model
* @param chatId Chat identifier
* @param filePath Path to the .prv file
* @return Result dictionary with owner_info, shared_info, and forwarded_list (nullable on error)
*/
- (nullable NSDictionary*)getFileAccessStatusListWithChatId:(NSString*)chatId
filePath:(NSString*)filePath;

// =============================================================================
// UNIFIED MESSAGE PROCESSING (PRIMARY METHOD)
// =============================================================================
Expand Down
2 changes: 1 addition & 1 deletion Privitty.framework/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.0.3</string>
<string>0.0.4</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>MinimumOSVersion</key>
Expand Down
Binary file modified Privitty.framework/Privitty
Binary file not shown.
Binary file modified Privitty.framework/_CodeSignature/CodeDirectory
Binary file not shown.
Binary file modified Privitty.framework/_CodeSignature/CodeRequirements-1
Binary file not shown.
8 changes: 4 additions & 4 deletions Privitty.framework/_CodeSignature/CodeResources
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
<dict>
<key>Headers/Privitty.h</key>
<data>
XOZiDTCe+NAWBhmcV7UHd7cQLlA=
7XJwNRZwtCUxomO8O7IL7fBgT74=
</data>
<key>Info.plist</key>
<data>
gVvxK6BoiqDGhhpTsPceMUMZ6Fg=
g3lk23mWzYzi7ThM/ASFGdIBWjw=
</data>
<key>Modules/module.modulemap</key>
<data>
Expand All @@ -23,11 +23,11 @@
<dict>
<key>hash</key>
<data>
XOZiDTCe+NAWBhmcV7UHd7cQLlA=
7XJwNRZwtCUxomO8O7IL7fBgT74=
</data>
<key>hash2</key>
<data>
lOUboneq2t71vqTNSqqXPH0sq0AwaZ1Nj9DQ6cW0Di8=
Ctj7MZKa+vxsHYPazciSO4F29ZdWOQJWl4BdECBZvS0=
</data>
</dict>
<key>Modules/module.modulemap</key>
Expand Down
Binary file modified Privitty.framework/_CodeSignature/CodeSignature
Binary file not shown.
14 changes: 12 additions & 2 deletions deltachat-ios.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
2F11E3E62E9FABD900CA4BB4 /* PrvContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2F11E3E52E9FABD900CA4BB4 /* PrvContext.swift */; };
2F2A09F22EC24FCC00A37097 /* Privitty.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F437DF72E94F68900297EED /* Privitty.framework */; };
2F2A09F32EC24FCC00A37097 /* Privitty.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 2F437DF72E94F68900297EED /* Privitty.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
2FB219D92EF167CB00A7E8A8 /* FileAccessControlViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FB219D82EF167CB00A7E8A8 /* FileAccessControlViewController.swift */; };
2FB219DC2EF1682500A7E8A8 /* FileAttachmentOptionsBottomSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FB219DB2EF1682500A7E8A8 /* FileAttachmentOptionsBottomSheet.swift */; };
2FB219DD2EF1682500A7E8A8 /* FileAccessRequestBottomSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2FB219DA2EF1682500A7E8A8 /* FileAccessRequestBottomSheet.swift */; };
3008CB7224F93EB900E6A617 /* AudioMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3008CB7124F93EB900E6A617 /* AudioMessageCell.swift */; };
3008CB7424F9436C00E6A617 /* AudioPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3008CB7324F9436C00E6A617 /* AudioPlayerView.swift */; };
3008CB7624F95B6D00E6A617 /* AudioController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3008CB7524F95B6D00E6A617 /* AudioController.swift */; };
Expand Down Expand Up @@ -333,6 +336,9 @@
21D6C9392606190600D0755A /* NotificationManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationManager.swift; sourceTree = "<group>"; };
2F11E3E52E9FABD900CA4BB4 /* PrvContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrvContext.swift; sourceTree = "<group>"; };
2F437DF72E94F68900297EED /* Privitty.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Privitty.framework; sourceTree = "<group>"; };
2FB219D82EF167CB00A7E8A8 /* FileAccessControlViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileAccessControlViewController.swift; sourceTree = "<group>"; };
2FB219DA2EF1682500A7E8A8 /* FileAccessRequestBottomSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileAccessRequestBottomSheet.swift; sourceTree = "<group>"; };
2FB219DB2EF1682500A7E8A8 /* FileAttachmentOptionsBottomSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileAttachmentOptionsBottomSheet.swift; sourceTree = "<group>"; };
3008CB7124F93EB900E6A617 /* AudioMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioMessageCell.swift; sourceTree = "<group>"; };
3008CB7324F9436C00E6A617 /* AudioPlayerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlayerView.swift; sourceTree = "<group>"; };
3008CB7524F95B6D00E6A617 /* AudioController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -699,8 +705,6 @@
/* Begin PBXFileSystemSynchronizedRootGroup section */
643B44782E0C2BD900AEE026 /* DcTests */ = {
isa = PBXFileSystemSynchronizedRootGroup;
exceptions = (
);
path = DcTests;
sourceTree = "<group>";
};
Expand Down Expand Up @@ -1152,6 +1156,9 @@
30DED712292EE4280040835D /* LogViewController.swift */,
0DACEEFB2EE47A7400043D27 /* ContentDetailsViewController.swift */,
0DACEF662EE4A7C600043D27 /* ContentDetailsViewController.swift */,
2FB219D82EF167CB00A7E8A8 /* FileAccessControlViewController.swift */,
2FB219DA2EF1682500A7E8A8 /* FileAccessRequestBottomSheet.swift */,
2FB219DB2EF1682500A7E8A8 /* FileAttachmentOptionsBottomSheet.swift */,
);
path = Controller;
sourceTree = "<group>";
Expand Down Expand Up @@ -1829,6 +1836,8 @@
B259D64329B771D5008FB706 /* BackupTransferViewController.swift in Sources */,
AE8519EA2272FDCA00ED86F0 /* DeviceContactsHandler.swift in Sources */,
302E592426A5CF4800DD4F58 /* ConnectivityViewController.swift in Sources */,
2FB219DC2EF1682500A7E8A8 /* FileAttachmentOptionsBottomSheet.swift in Sources */,
2FB219DD2EF1682500A7E8A8 /* FileAccessRequestBottomSheet.swift in Sources */,
78ED838321D5379000243125 /* TextFieldCell.swift in Sources */,
305702A124C6453700D84EFC /* TypeAlias.swift in Sources */,
AE19887523EB264000B4CD5F /* HelpViewController.swift in Sources */,
Expand Down Expand Up @@ -1872,6 +1881,7 @@
D8C1B0DD2CE7421C00C233A7 /* ShareProxyViewController.swift in Sources */,
AE76E5EE242BF2EA003CF461 /* WelcomeViewController.swift in Sources */,
3052C60A253F082E007D13EA /* MessageLabelDelegate.swift in Sources */,
2FB219D92EF167CB00A7E8A8 /* FileAccessControlViewController.swift in Sources */,
AE0AA9562478191900D42A7F /* GridCollectionViewFlowLayout.swift in Sources */,
303492A5257546B400A523D0 /* DraftPreview.swift in Sources */,
305961D02346125100C80F33 /* NSAttributedString+Extensions.swift in Sources */,
Expand Down
76 changes: 65 additions & 11 deletions deltachat-ios/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@
relayHelper = RelayHelper.setup(dcAccounts.getSelected())
appCoordinator = AppCoordinator(window: window, dcAccounts: dcAccounts)
locationManager = LocationManager(dcAccounts: dcAccounts)
UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplication.backgroundFetchIntervalMinimum)

Check warning on line 148 in deltachat-ios/AppDelegate.swift

View workflow job for this annotation

GitHub Actions / build

'setMinimumBackgroundFetchInterval' was deprecated in iOS 13.0: Use a BGAppRefreshTask in the BackgroundTasks framework instead
notificationManager = NotificationManager(dcAccounts: dcAccounts)
setStockTranslations()
dcAccounts.startIo()
Expand Down Expand Up @@ -652,20 +652,74 @@
// Process the Privitty message
let result = PrvContext.shared.processIncomingMessage(chatId: chatId, pdu: messageText, direction: "incoming")

logger.debug("Privitty: Result: \(result)")

if result.success {
logger.info("Privitty: Message processed successfully")

// Check if response has PDU to send back
if let data = result.data,
let dataData = data["data"] as? [String: Any],
let pdu = dataData["pdu"] as? String {
logger.debug("Privitty: PDU size: \(pdu.count)")

// Send the PDU message back to the chat
let responseMsg = dcContext.newMessage(viewType: DC_MSG_TEXT)
responseMsg.text = pdu
dcContext.sendMessage(chatId: chatId, message: responseMsg)
logger.info("Privitty: Response message sent to chat \(chatId)")
// Parse response structure: data.data.pdu and data.data.chat_id (matches Android line 206)
if let data = result.data {
logger.debug("Privitty: Response data exists, keys: \(Array(data.keys))")

// Check if response has "data" key (matches Android: responseJson.has("data"))
if let dataDataJson = data["data"] as? [String: Any] {
logger.debug("Privitty: Found data.data, keys: \(Array(dataDataJson.keys))")

// Check if dataDataJson has "data" key (matches Android: dataDataJson.has("data"))
// Try data.data.data first (Android structure), then fall back to data.data (iOS structure)
var dataJson: [String: Any]?

if let nestedData = dataDataJson["data"] as? [String: Any] {
// Triple nested: data.data.data (Android structure)
dataJson = nestedData
logger.debug("Privitty: Found data.data.data (triple nested - Android structure)")
} else if dataDataJson["pdu"] != nil {
// Double nested: data.data (iOS structure - pdu and chat_id are directly here)
dataJson = dataDataJson
logger.debug("Privitty: Using data.data directly (double nested - iOS structure)")
}

if let dataJson = dataJson {
logger.debug("Privitty: Processing dataJson, keys: \(Array(dataJson.keys))")

// Check if dataJson has "pdu" key (matches Android: dataJson.has("pdu"))
if let pdu = dataJson["pdu"] as? String {
logger.debug("Privitty: Found PDU, size: \(pdu.count)")

// Extract chat_id from response (matches Android: dataJson.has("chat_id"))
// Note: chat_id might be Int or String, handle both cases
var puntChatId: Int?
if let chatIdInt = dataJson["chat_id"] as? Int {
puntChatId = chatIdInt
} else if let chatIdStr = dataJson["chat_id"] as? String,
let chatIdInt = Int(chatIdStr) {
puntChatId = chatIdInt
}

if let puntChatId = puntChatId {
// Use chat_id from response to send PDU (matches Android: puntChatId)
let msg = dcContext.newMessage(viewType: DC_MSG_TEXT)
msg.text = pdu
dcContext.sendMessage(chatId: puntChatId, message: msg)
logger.debug("Privitty: Privitty PDU sent - chatId: \(chatId), puntChatId: \(puntChatId)")
} else {
logger.error("Privitty: chat ID is missing or invalid for the requested PDU")
logger.error("Privitty: chat_id value: \(String(describing: dataJson["chat_id"])), type: \(type(of: dataJson["chat_id"]))")
}
} else {
logger.error("Privitty: PDU is missing in dataJson")
logger.error("Privitty: pdu value: \(String(describing: dataJson["pdu"])), type: \(type(of: dataJson["pdu"]))")
}
} else {
logger.error("Privitty: Could not extract dataJson from response")
logger.error("Privitty: dataDataJson does not have nested 'data' key and does not contain 'pdu' directly")
}
} else {
logger.error("Privitty: data.data is missing or not a dictionary")
logger.error("Privitty: data[\"data\"] value: \(String(describing: data["data"])), type: \(type(of: data["data"]))")
}
} else {
logger.error("Privitty: Response data is nil")
}
} else {
logger.error("Privitty: Failed to process message: \(result.error ?? "Unknown error")")
Expand Down
6 changes: 3 additions & 3 deletions deltachat-ios/Base.lproj/LaunchScreen.storyboard
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
</constraints>
</imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="privitty_name_white" translatesAutoresizingMaskIntoConstraints="NO" id="imageWordmark">
<rect key="frame" x="0.0" y="204" width="256" height="90"/>
<rect key="frame" x="0.0" y="204" width="301.813" height="58.92"/>
<constraints>
<constraint firstAttribute="height" constant="90" id="wordmark-height"/>
<constraint firstAttribute="width" constant="256" id="wordmark-width"/>
<constraint firstAttribute="height" constant="58.92" id="wordmark-height"/>
<constraint firstAttribute="width" constant="301.813" id="wordmark-width"/>
</constraints>
</imageView>
</subviews>
Expand Down
Loading
Loading