Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
921e7c3
feat: preserve E2EE key sets during setup
marinofaggiana Aug 20, 2026
0190ffa
feat: support read-only access with archived E2EE keys
marinofaggiana Aug 20, 2026
e9d15b6
fix: reuse root metadata key for E2EE v2 child folders
marinofaggiana Aug 20, 2026
462e11a
fix: enforce E2EE write access before metadata changes
marinofaggiana Aug 20, 2026
24a6948
fix: handle empty users in E2EE v2 metadata
marinofaggiana Aug 20, 2026
9525d31
fix: enforce E2EE key set write access
marinofaggiana Aug 20, 2026
ce4d263
test: verify E2EE archiving preserves active credentials
marinofaggiana Aug 20, 2026
b4daac2
fix: handle changed E2EE server keys safely
marinofaggiana Aug 20, 2026
8764ce6
fix: validate E2EE server keys once per active cycle
marinofaggiana Aug 21, 2026
c96d774
refactor: clarify metadata key decryption checks
marinofaggiana Aug 21, 2026
13903af
Merge remote-tracking branch 'origin/master' into 8-handle-keys-that-…
marinofaggiana Aug 24, 2026
dbf0ff2
fix: require password for E2EE key deletion
marinofaggiana Aug 24, 2026
bf9d458
fix: allow passwordless E2EE key management
marinofaggiana Aug 24, 2026
70d0b0a
cleaning
marinofaggiana Aug 24, 2026
05b64a2
rename
marinofaggiana Aug 25, 2026
48357d1
fix: validate E2EE keys against user certificates
marinofaggiana Aug 25, 2026
10e384c
fix: refresh plus menu when E2EE preference changes
marinofaggiana Aug 25, 2026
08d0a52
chore: prepare 34.2.0 release
marinofaggiana Aug 25, 2026
ed6405b
fix: prevent sensitive E2EE data from being logged
marinofaggiana Aug 25, 2026
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
46 changes: 41 additions & 5 deletions Nextcloud.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@
2C33C48623E2C475005F963B /* Notification Service Extension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 2C33C47F23E2C475005F963B /* Notification Service Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
370D26AF248A3D7A00121797 /* NCCellMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D26AE248A3D7A00121797 /* NCCellMain.swift */; };
A1B2C3D430B0000100ABCDEF /* NCMediaViewerLoadingPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1B2C3D330B0000100ABCDEF /* NCMediaViewerLoadingPolicy.swift */; };
A1E2EE010000000000000002 /* NCEndToEndKeySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE010000000000000001 /* NCEndToEndKeySet.swift */; };
A1E2EE010000000000000003 /* NCEndToEndKeySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE010000000000000001 /* NCEndToEndKeySet.swift */; };
A1E2EE010000000000000004 /* NCEndToEndKeySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE010000000000000001 /* NCEndToEndKeySet.swift */; };
A1E2EE010000000000000005 /* NCEndToEndKeySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE010000000000000001 /* NCEndToEndKeySet.swift */; };
A1E2EE010000000000000006 /* NCEndToEndKeySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE010000000000000001 /* NCEndToEndKeySet.swift */; };
A1E2EE010000000000000007 /* NCEndToEndKeySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE010000000000000001 /* NCEndToEndKeySet.swift */; };
A1E2EE010000000000000008 /* NCEndToEndKeySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE010000000000000001 /* NCEndToEndKeySet.swift */; };
A1E2EE01000000000000000A /* NCEndToEndKeySetArchiveTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE010000000000000009 /* NCEndToEndKeySetArchiveTests.swift */; };
A1E2EE020000000000000003 /* NCEndToEndKeySetAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE020000000000000001 /* NCEndToEndKeySetAccess.swift */; };
A1E2EE020000000000000004 /* NCEndToEndKeySetAccess.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE020000000000000001 /* NCEndToEndKeySetAccess.swift */; };
A1E2EE020000000000000005 /* NCEndToEndKeySetResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE020000000000000002 /* NCEndToEndKeySetResolver.swift */; };
A1E2EE020000000000000006 /* NCEndToEndKeySetResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE020000000000000002 /* NCEndToEndKeySetResolver.swift */; };
A1E2EE020000000000000008 /* NCEndToEndKeySetResolverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E2EE020000000000000007 /* NCEndToEndKeySetResolverTests.swift */; };
A5A87F9E4B0E4441A6A4BC20 /* NCContextMenuProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB7697C94BA14450A0867940 /* NCContextMenuProfile.swift */; };
AA3C85E82D36B08C00F74F12 /* UITestBackend.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3C85E72D36B08C00F74F12 /* UITestBackend.swift */; };
AA3C85EB2D36BBFB00F74F12 /* OCSResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3C85EA2D36BBF400F74F12 /* OCSResponse.swift */; };
Expand Down Expand Up @@ -1218,6 +1231,11 @@
370D26AE248A3D7A00121797 /* NCCellMain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCCellMain.swift; sourceTree = "<group>"; };
8932E90EC4278026D86CCCC9 /* NCContextMenuComment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCContextMenuComment.swift; sourceTree = "<group>"; };
A1B2C3D330B0000100ABCDEF /* NCMediaViewerLoadingPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCMediaViewerLoadingPolicy.swift; sourceTree = "<group>"; };
A1E2EE010000000000000001 /* NCEndToEndKeySet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCEndToEndKeySet.swift; sourceTree = "<group>"; };
A1E2EE010000000000000009 /* NCEndToEndKeySetArchiveTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCEndToEndKeySetArchiveTests.swift; sourceTree = "<group>"; };
A1E2EE020000000000000001 /* NCEndToEndKeySetAccess.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCEndToEndKeySetAccess.swift; sourceTree = "<group>"; };
A1E2EE020000000000000002 /* NCEndToEndKeySetResolver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCEndToEndKeySetResolver.swift; sourceTree = "<group>"; };
A1E2EE020000000000000007 /* NCEndToEndKeySetResolverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCEndToEndKeySetResolverTests.swift; sourceTree = "<group>"; };
AA3C85E72D36B08C00F74F12 /* UITestBackend.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestBackend.swift; sourceTree = "<group>"; };
AA3C85EA2D36BBF400F74F12 /* OCSResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OCSResponse.swift; sourceTree = "<group>"; };
AA3C85ED2D36BCCB00F74F12 /* SharesResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharesResponse.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2197,6 +2215,8 @@
AA52EB442D42AC500089C348 /* NextcloudUnitTests */ = {
isa = PBXGroup;
children = (
A1E2EE010000000000000009 /* NCEndToEndKeySetArchiveTests.swift */,
A1E2EE020000000000000007 /* NCEndToEndKeySetResolverTests.swift */,
AABBCC0330A8000100F0A001 /* NCMediaPlaybackOptionsTests.swift */,
AABBCC0730A8000100F0A001 /* NCVideoPlaybackPresentationContextTests.swift */,
AABBCC0930A8000100F0A001 /* NCMediaViewerModelTests.swift */,
Expand Down Expand Up @@ -2822,6 +2842,7 @@
F768820D2C0DD1E7001CF441 /* E2EE */ = {
isa = PBXGroup;
children = (
A1E2EE010000000000000001 /* NCEndToEndKeySet.swift */,
F71070AA2F7E49E100AEE58A /* NCEndToEndSetup.swift */,
F76882102C0DD1E7001CF441 /* NCManageE2EEModel.swift */,
F768820E2C0DD1E7001CF441 /* NCManageE2EEView.swift */,
Expand Down Expand Up @@ -3278,6 +3299,8 @@
children = (
F70CAE381F8CF31A008125FD /* NCEndToEndEncryption.h */,
F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */,
A1E2EE020000000000000001 /* NCEndToEndKeySetAccess.swift */,
A1E2EE020000000000000002 /* NCEndToEndKeySetResolver.swift */,
F7F878AD1FB9E3B900599E4F /* NCEndToEndMetadata.swift */,
F72944F12A84246400246839 /* NCEndToEndMetadataV2.swift */,
F72944F42A8424F800246839 /* NCEndToEndMetadataV1.swift */,
Expand Down Expand Up @@ -4475,6 +4498,7 @@
F7817CFF29802D1A00FFBC65 /* NCPushNotificationEncryption.m in Sources */,
F798F0EC2588060A000DAFFD /* UIColor+Extension.swift in Sources */,
F76882372C0DD22F001CF441 /* NCPreferences.swift in Sources */,
A1E2EE010000000000000002 /* NCEndToEndKeySet.swift in Sources */,
F73EF7E52B02266D0087E6E9 /* NCManageDatabase+Trash.swift in Sources */,
F7CAFE232F17A37C00DB35A5 /* ProgressQuantizer.swift in Sources */,
F764C3E42FFB7DFA00029FD5 /* NCManageDatabase+MediaMetadataBackfill.swift in Sources */,
Expand All @@ -4491,6 +4515,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A1E2EE01000000000000000A /* NCEndToEndKeySetArchiveTests.swift in Sources */,
A1E2EE020000000000000008 /* NCEndToEndKeySetResolverTests.swift in Sources */,
AABBCC0430A8000100F0A001 /* NCMediaPlaybackOptionsTests.swift in Sources */,
AABBCC0830A8000100F0A001 /* NCVideoPlaybackPresentationContextTests.swift in Sources */,
AABBCC0A30A8000100F0A001 /* NCMediaViewerModelTests.swift in Sources */,
Expand Down Expand Up @@ -4547,6 +4573,7 @@
F763413B2EBE5DB10056F538 /* FileProviderExtension.swift in Sources */,
F763413D2EBE5DBB0056F538 /* FileProviderExtension+Thumbnail.swift in Sources */,
F76882382C0DD22F001CF441 /* NCPreferences.swift in Sources */,
A1E2EE010000000000000003 /* NCEndToEndKeySet.swift in Sources */,
F70716E62987F81500E72C1D /* DocumentActionViewController.swift in Sources */,
F763412A2EBE10F00056F538 /* NCUtilityFileSystem.swift in Sources */,
F760A4942FE95D33001B212E /* NetworkingTasks.swift in Sources */,
Expand Down Expand Up @@ -4657,6 +4684,8 @@
F7A573692E190387009C9257 /* NCShareExtensionData.swift in Sources */,
F7BDC1D4300F440A00C5D9FA /* NCManageDatabase+MediaPreviewBackfill.swift in Sources */,
F7BD71E62636EAFC00643C34 /* NCNetworkingE2EE.swift in Sources */,
A1E2EE020000000000000003 /* NCEndToEndKeySetAccess.swift in Sources */,
A1E2EE020000000000000005 /* NCEndToEndKeySetResolver.swift in Sources */,
F7F878AF1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */,
F7327E3B2B73B8D600A462C7 /* Array+Extension.swift in Sources */,
F7D7A76C2DCDD437003D2007 /* NCManageDatabase+AutoUpload.swift in Sources */,
Expand Down Expand Up @@ -4688,6 +4717,7 @@
F763D2A02A249C4500A3C901 /* NCManageDatabase+Capabilities.swift in Sources */,
F757CC8529E7F88B00F31428 /* NCManageDatabase+Groupfolders.swift in Sources */,
F768823A2C0DD230001CF441 /* NCPreferences.swift in Sources */,
A1E2EE010000000000000004 /* NCEndToEndKeySet.swift in Sources */,
F737DA9E2B7B893C0063BAFC /* NCPasscode.swift in Sources */,
F7C30DF7291BC0D30017149B /* NCNetworkingE2EEUpload.swift in Sources */,
F7C687EC2D22BDE5004757BC /* NCManageDatabase+RecommendedFiles.swift in Sources */,
Expand Down Expand Up @@ -4737,6 +4767,7 @@
F7BDC1D6300F440A00C5D9FA /* NCManageDatabase+MediaPreviewBackfill.swift in Sources */,
F72EA95A28B7BD0D00C88F0C /* FilesWidgetView.swift in Sources */,
F768823C2C0DD231001CF441 /* NCPreferences.swift in Sources */,
A1E2EE010000000000000005 /* NCEndToEndKeySet.swift in Sources */,
F71F6D082B6A6A5E00F1EB15 /* ThreadSafeArray.swift in Sources */,
F78302FE28B4C44700B84583 /* NCBrand.swift in Sources */,
F749B64B297B0CBB00087535 /* NCManageDatabase+Share.swift in Sources */,
Expand Down Expand Up @@ -4827,6 +4858,7 @@
F71F6D0B2B6A6A5E00F1EB15 /* ThreadSafeArray.swift in Sources */,
F771E3F820E239B500AFB62D /* FileProviderExtension+Thumbnail.swift in Sources */,
F76882392C0DD230001CF441 /* NCPreferences.swift in Sources */,
A1E2EE010000000000000006 /* NCEndToEndKeySet.swift in Sources */,
F77DD6AC2C5CC093009448FB /* NCSession.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -4855,6 +4887,7 @@
F32FADA92D1176E3007035E2 /* UIButton+Extension.swift in Sources */,
F7DF7B3F2F1A2EF900514020 /* WarningBannerView.swift in Sources */,
F768822C2C0DD1E7001CF441 /* NCPreferences.swift in Sources */,
A1E2EE010000000000000007 /* NCEndToEndKeySet.swift in Sources */,
F7CAFE1D2F17A35F00DB35A5 /* ProgressQuantizer.swift in Sources */,
F7EDBB4B2FA89F6800098C42 /* NCLivePhotoViewerContentView.swift in Sources */,
F3754A7D2CF87D600009312E /* SetupPasscodeView.swift in Sources */,
Expand Down Expand Up @@ -5035,6 +5068,8 @@
F3CA337D2D0B2B6C00672333 /* AlbumModel.swift in Sources */,
AF93471A27E2361E002537EE /* NCShareHeader.swift in Sources */,
F7F878AE1FB9E3B900599E4F /* NCEndToEndMetadata.swift in Sources */,
A1E2EE020000000000000004 /* NCEndToEndKeySetAccess.swift in Sources */,
A1E2EE020000000000000006 /* NCEndToEndKeySetResolver.swift in Sources */,
F7A7FDDD2C2DBD6200E9A93A /* NCDeepLinkHandler.swift in Sources */,
F778231E2C42C07C001BB94F /* NCCollectionViewCommon+MediaLayout.swift in Sources */,
F710D1F52405770F00A6033D /* NCViewerPDF.swift in Sources */,
Expand Down Expand Up @@ -5294,6 +5329,7 @@
F7A8D73C28F181BC008BBE1C /* NCBrand.swift in Sources */,
F711A4DE2AF92CAE00095DD8 /* NCUtility+Date.swift in Sources */,
F768823B2C0DD231001CF441 /* NCPreferences.swift in Sources */,
A1E2EE010000000000000008 /* NCEndToEndKeySet.swift in Sources */,
AA8D31532D41052300FE2775 /* NCManageDatabase+DownloadLimit.swift in Sources */,
F7A8D74228F18261008BBE1C /* NCUtility.swift in Sources */,
F7E250002FE1000000000006 /* NCDocumentEditorSupport.swift in Sources */,
Expand Down Expand Up @@ -6347,7 +6383,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 0;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = NKUJUXUJ3B;
Expand All @@ -6374,7 +6410,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 34.1.4;
MARKETING_VERSION = 34.2.0;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "-v";
OTHER_LDFLAGS = "";
Expand Down Expand Up @@ -6415,7 +6451,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 0;
DEAD_CODE_STRIPPING = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = NKUJUXUJ3B;
Expand All @@ -6440,7 +6476,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 34.1.4;
MARKETING_VERSION = 34.2.0;
ONLY_ACTIVE_ARCH = YES;
OTHER_CFLAGS = "-v";
OTHER_LDFLAGS = "";
Expand Down Expand Up @@ -6685,7 +6721,7 @@
repositoryURL = "https://github.com/nextcloud/NextcloudKit";
requirement = {
kind = exactVersion;
version = 7.4.3;
version = 7.5.0;
};
};
F788ECC5263AAAF900ADC67F /* XCRemoteSwiftPackageReference "MarkdownKit" */ = {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Share/NCShareExtension.swift
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,10 @@ extension NCShareExtension {

@MainActor
func uploadAndExit() async {
// A Share extension process can be reused by the system. Treat each
// explicit share operation as a new server-key validation cycle.
await NCNetworkingE2EE.beginNewServerKeyValidationCycle()

var error: NKError?
guard let window = self.view.window else {
return
Expand Down
110 changes: 110 additions & 0 deletions Tests/NextcloudUnitTests/NCEndToEndKeySetArchiveTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// SPDX-FileCopyrightText: Nextcloud GmbH
// SPDX-FileCopyrightText: 2026 Marino Faggiana
// SPDX-License-Identifier: GPL-3.0-or-later

import Foundation
import Testing
@testable import Nextcloud

@Suite("End-to-end key set archive")
struct NCEndToEndKeySetArchiveTests {
@Test("Archiving does not change the active credentials")
func preservesNormalActiveCredentials() throws {
let account = "e2ee-archive-\(UUID().uuidString)"
let preferences = NCPreferences()
defer {
preferences.clearAllKeysEndToEnd(account: account)
}

setKeySet(on: preferences, account: account)
try preferences.archiveCurrentEndToEndKeySet(account: account)

#expect(preferences.isEndToEndEnabled(account: account))
#expect(preferences.getEndToEndCertificate(account: account) == "certificate")
#expect(preferences.getEndToEndPrivateKey(account: account) == "private-key")
#expect(preferences.getEndToEndPublicKey(account: account) == "public-key")
#expect(preferences.getEndToEndPassphrase(account: account) == "passphrase")
}

@Test("Archiving preserves active credentials after they are cleared")
func preservesActiveCredentials() throws {
let account = "e2ee-archive-\(UUID().uuidString)"
let preferences = NCPreferences()
defer {
preferences.clearAllKeysEndToEnd(account: account)
}

setKeySet(on: preferences, account: account)
let archivedKeySet = try preferences.archiveCurrentEndToEndKeySet(account: account)
let snapshot = try #require(archivedKeySet)

preferences.clearCurrentKeysEndToEnd(account: account)

#expect(preferences.getEndToEndCertificate(account: account) == nil)
#expect(preferences.getEndToEndPrivateKey(account: account) == nil)
#expect(preferences.getEndToEndPublicKey(account: account) == nil)
#expect(preferences.getEndToEndPassphrase(account: account) == nil)

let archivedKeySets = try preferences.getArchivedEndToEndKeySets(account: account)
#expect(archivedKeySets == [snapshot])
#expect(snapshot.certificate == "certificate")
#expect(snapshot.privateKey == "private-key")
#expect(snapshot.publicKey == "public-key")
#expect(snapshot.passphrase == "passphrase")
}

@Test("Explicit local removal also clears stale server-key state")
func removalClearsStaleState() {
let account = "e2ee-archive-\(UUID().uuidString)"
let preferences = NCPreferences()

preferences.setEndToEndServerKeyStale(account: account, stale: true)
preferences.clearAllKeysEndToEnd(account: account)

#expect(!preferences.isEndToEndServerKeyStale(account: account))
}

@Test("Archiving the same credentials does not create duplicates")
func avoidsDuplicates() throws {
let account = "e2ee-archive-\(UUID().uuidString)"
let preferences = NCPreferences()
defer {
preferences.clearAllKeysEndToEnd(account: account)
}

setKeySet(on: preferences, account: account)
let firstArchivedKeySet = try preferences.archiveCurrentEndToEndKeySet(account: account)
let secondArchivedKeySet = try preferences.archiveCurrentEndToEndKeySet(account: account)
let firstSnapshot = try #require(firstArchivedKeySet)
let secondSnapshot = try #require(secondArchivedKeySet)

#expect(secondSnapshot.identifier == firstSnapshot.identifier)
#expect(try preferences.getArchivedEndToEndKeySets(account: account).count == 1)
}

@Test("A partial setup is archived when it contains usable key material")
func preservesPartialKeyMaterial() throws {
let account = "e2ee-archive-\(UUID().uuidString)"
let preferences = NCPreferences()
defer {
preferences.clearAllKeysEndToEnd(account: account)
}

preferences.setEndToEndPrivateKey(account: account, privateKey: "private-key")

let archivedKeySet = try preferences.archiveCurrentEndToEndKeySet(account: account)
let snapshot = try #require(archivedKeySet)

#expect(snapshot.privateKey == "private-key")
#expect(snapshot.certificate == nil)
#expect(snapshot.publicKey == nil)
#expect(snapshot.passphrase == nil)
}

private func setKeySet(on preferences: NCPreferences, account: String) {
preferences.setEndToEndCertificate(account: account, certificate: "certificate")
preferences.setEndToEndPrivateKey(account: account, privateKey: "private-key")
preferences.setEndToEndPublicKey(account: account, publicKey: "public-key")
preferences.setEndToEndPassphrase(account: account, passphrase: "passphrase")
}
}
Loading
Loading