feat: copper accent theme, always-expanded group filter, app icon; rename MyPass to KeeVault

- Custom copper AccentColor and warm VaultBackground color assets (light/dark),
  applied to both the main app and the AutoFill extension (which needed its own
  copy of the asset catalog plus ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME
  and an explicit .tint() modifier, since extensions don't pick up the app-wide
  accent color the same way a full SwiftUI App/Scene does).
- GroupFilterView no longer uses DisclosureGroup for subgroups -- the whole tree
  renders always-expanded (indented per depth) so active filters are visible at
  a glance instead of requiring tap-to-expand.
- Added a placeholder app icon (padlock glyph, light/dark/tinted variants plus
  macOS sizes) -- previously the icon slot existed but had no actual images,
  which blocks App Store/TestFlight archive validation.
- Added ITSAppUsesNonExemptEncryption = NO (standard encryption only, via
  KeePassKit) to skip the export-compliance prompt on each upload.
- Renamed the app from MyPass to KeeVault throughout: Xcode project/targets/
  schemes, the MyPassCore package (now KeeVaultCore) and every import site,
  folder and file names, bundle identifiers (org.antiloop222.keevault) and
  their App Group/Keychain-group entitlements, and remaining UI/string
  references -- MyPass was already taken as an App Store app name.
This commit is contained in:
2026-09-20 15:05:19 +02:00
parent a8d612f745
commit 8bba64076f
74 changed files with 363 additions and 176 deletions
@@ -0,0 +1,38 @@
{
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.710",
"green" : "0.396",
"blue" : "0.114",
"alpha" : "1.000"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.890",
"green" : "0.635",
"blue" : "0.357",
"alpha" : "1.000"
}
}
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,38 @@
{
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.980",
"green" : "0.957",
"blue" : "0.925",
"alpha" : "1.000"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.141",
"green" : "0.125",
"blue" : "0.094",
"alpha" : "1.000"
}
}
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
+2 -2
View File
@@ -6,11 +6,11 @@
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.org.antiloop222.mypass</string>
<string>group.org.antiloop222.keevault</string>
</array>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)org.antiloop222.mypass</string>
<string>$(AppIdentifierPrefix)org.antiloop222.keevault</string>
</array>
</dict>
</plist>
@@ -7,16 +7,16 @@
import AuthenticationServices
import SwiftUI
import MyPassCore
import KeeVaultCore
final class CredentialProviderViewController: ASCredentialProviderViewController {
private let session = VaultSession()
private let bookmarkService = FileBookmarkService()
private let keychainStore = KeychainStore(accessGroup: "F2KB6W8N4R.org.antiloop222.mypass")
private let keychainStore = KeychainStore(accessGroup: "F2KB6W8N4R.org.antiloop222.keevault")
private let biometricService = BiometricAuthService()
// Called when the user selects MyPass from the QuickType bar.
// Called when the user selects KeeVault from the QuickType bar.
override func prepareCredentialList(for serviceIdentifiers: [ASCredentialServiceIdentifier]) {
let ids = serviceIdentifiers.map(\.identifier)
showUI(serviceIdentifiers: ids)
+3 -1
View File
@@ -1,6 +1,6 @@
// AutoFill/Views/CredentialListView.swift
import SwiftUI
import MyPassCore
import KeeVaultCore
struct CredentialListView: View {
@ObservedObject var vm: ExtensionViewModel
@@ -40,6 +40,8 @@ struct CredentialListView: View {
}
}
}
.scrollContentBackground(.hidden)
.background(Color("VaultBackground"))
.searchable(text: $searchQuery, prompt: "Search…")
}
}
+7 -5
View File
@@ -1,7 +1,7 @@
// AutoFill/Views/ExtensionUnlockView.swift
import SwiftUI
import Combine
import MyPassCore
import KeeVaultCore
/// Root view for the extension -- shows unlock screen or credential list depending on state.
struct ExtensionRootView: View {
@@ -36,7 +36,8 @@ struct ExtensionRootView: View {
CredentialListView(vm: vm)
}
}
.navigationTitle("MyPass")
.background(Color("VaultBackground"))
.navigationTitle("KeeVault")
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .cancellationAction) {
@@ -44,6 +45,7 @@ struct ExtensionRootView: View {
}
}
}
.tint(Color("AccentColor"))
.task { await vm.tryBiometricUnlock() }
}
@@ -74,8 +76,8 @@ struct ExtensionRootView: View {
}
if !vm.hasVault || vm.errorMessage != nil {
Link(destination: URL(string: "mypass://unlock")!) {
Label("Open MyPass to set up vault", systemImage: "arrow.up.right")
Link(destination: URL(string: "keevault://unlock")!) {
Label("Open KeeVault to set up vault", systemImage: "arrow.up.right")
.font(.caption)
}
}
@@ -140,7 +142,7 @@ final class ExtensionViewModel: ObservableObject {
guard canUseBiometrics, session.isLocked else { return }
isUnlocking = true
do {
try await biometricService.authenticate(reason: "Unlock MyPass")
try await biometricService.authenticate(reason: "Unlock KeeVault")
try performUnlockFromKeychain()
} catch {
errorMessage = error.localizedDescription
@@ -7,10 +7,10 @@
objects = {
/* Begin PBXBuildFile section */
205678DB2FC0EB5200251C6B /* MyPassCore in Frameworks */ = {isa = PBXBuildFile; productRef = 205678DA2FC0EB5200251C6B /* MyPassCore */; };
205678DB2FC0EB5200251C6B /* KeeVaultCore in Frameworks */ = {isa = PBXBuildFile; productRef = 205678DA2FC0EB5200251C6B /* KeeVaultCore */; };
2096B432305EC2B200C2F253 /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 205678E32FC0F52A00251C6B /* AuthenticationServices.framework */; };
2096B43D305EC2B200C2F253 /* AutoFill.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 2096B431305EC2B200C2F253 /* AutoFill.appex */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
67DE2FCFC21FD6DF5E761C87 /* MyPassCore in Frameworks */ = {isa = PBXBuildFile; productRef = 205678DA2FC0EB5200251C6B /* MyPassCore */; };
67DE2FCFC21FD6DF5E761C87 /* KeeVaultCore in Frameworks */ = {isa = PBXBuildFile; productRef = 205678DA2FC0EB5200251C6B /* KeeVaultCore */; };
982CE38F924E4FD387BC2C20 /* BiometricAuthService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C7DFA4A59640D7BF6B4960 /* BiometricAuthService.swift */; };
EABAC2B148F845C8A20EC2CC /* FileBookmarkService.swift in Sources */ = {isa = PBXBuildFile; fileRef = ADBBB9F1BA62473294D2B5B5 /* FileBookmarkService.swift */; };
/* End PBXBuildFile section */
@@ -21,14 +21,14 @@
containerPortal = 2056788B2FBF9CBB00251C6B /* Project object */;
proxyType = 1;
remoteGlobalIDString = 205678922FBF9CBB00251C6B;
remoteInfo = MyPass;
remoteInfo = KeeVault;
};
205678AD2FBF9CBC00251C6B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 2056788B2FBF9CBB00251C6B /* Project object */;
proxyType = 1;
remoteGlobalIDString = 205678922FBF9CBB00251C6B;
remoteInfo = MyPass;
remoteInfo = KeeVault;
};
2096B43B305EC2B200C2F253 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
@@ -54,13 +54,13 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
205678932FBF9CBB00251C6B /* MyPass.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MyPass.app; sourceTree = BUILT_PRODUCTS_DIR; };
205678A22FBF9CBC00251C6B /* MyPassTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MyPassTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
205678AC2FBF9CBC00251C6B /* MyPassUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MyPassUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
205678932FBF9CBB00251C6B /* KeeVault.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KeeVault.app; sourceTree = BUILT_PRODUCTS_DIR; };
205678A22FBF9CBC00251C6B /* KeeVaultTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeeVaultTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
205678AC2FBF9CBC00251C6B /* KeeVaultUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeeVaultUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
205678E32FC0F52A00251C6B /* AuthenticationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AuthenticationServices.framework; path = System/Library/Frameworks/AuthenticationServices.framework; sourceTree = SDKROOT; };
2096B431305EC2B200C2F253 /* AutoFill.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = AutoFill.appex; sourceTree = BUILT_PRODUCTS_DIR; };
ADBBB9F1BA62473294D2B5B5 /* FileBookmarkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = FileBookmarkService.swift; path = MyPass/Services/FileBookmarkService.swift; sourceTree = SOURCE_ROOT; };
D6C7DFA4A59640D7BF6B4960 /* BiometricAuthService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BiometricAuthService.swift; path = MyPass/Services/BiometricAuthService.swift; sourceTree = SOURCE_ROOT; };
ADBBB9F1BA62473294D2B5B5 /* FileBookmarkService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = FileBookmarkService.swift; path = KeeVault/Services/FileBookmarkService.swift; sourceTree = SOURCE_ROOT; };
D6C7DFA4A59640D7BF6B4960 /* BiometricAuthService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = BiometricAuthService.swift; path = KeeVault/Services/BiometricAuthService.swift; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
@@ -74,19 +74,19 @@
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
/* Begin PBXFileSystemSynchronizedRootGroup section */
205678952FBF9CBB00251C6B /* MyPass */ = {
205678952FBF9CBB00251C6B /* KeeVault */ = {
isa = PBXFileSystemSynchronizedRootGroup;
path = MyPass;
path = KeeVault;
sourceTree = "<group>";
};
205678A52FBF9CBC00251C6B /* MyPassTests */ = {
205678A52FBF9CBC00251C6B /* KeeVaultTests */ = {
isa = PBXFileSystemSynchronizedRootGroup;
path = MyPassTests;
path = KeeVaultTests;
sourceTree = "<group>";
};
205678AF2FBF9CBC00251C6B /* MyPassUITests */ = {
205678AF2FBF9CBC00251C6B /* KeeVaultUITests */ = {
isa = PBXFileSystemSynchronizedRootGroup;
path = MyPassUITests;
path = KeeVaultUITests;
sourceTree = "<group>";
};
2096B433305EC2B200C2F253 /* AutoFill */ = {
@@ -104,7 +104,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
205678DB2FC0EB5200251C6B /* MyPassCore in Frameworks */,
205678DB2FC0EB5200251C6B /* KeeVaultCore in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -127,7 +127,7 @@
buildActionMask = 2147483647;
files = (
2096B432305EC2B200C2F253 /* AuthenticationServices.framework in Frameworks */,
67DE2FCFC21FD6DF5E761C87 /* MyPassCore in Frameworks */,
67DE2FCFC21FD6DF5E761C87 /* KeeVaultCore in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -146,9 +146,9 @@
2056788A2FBF9CBB00251C6B = {
isa = PBXGroup;
children = (
205678952FBF9CBB00251C6B /* MyPass */,
205678A52FBF9CBC00251C6B /* MyPassTests */,
205678AF2FBF9CBC00251C6B /* MyPassUITests */,
205678952FBF9CBB00251C6B /* KeeVault */,
205678A52FBF9CBC00251C6B /* KeeVaultTests */,
205678AF2FBF9CBC00251C6B /* KeeVaultUITests */,
2096B433305EC2B200C2F253 /* AutoFill */,
1A2B3C4D5E6F7A8B9C0D1E2F /* AutoFill Shared Services */,
205678E22FC0F52A00251C6B /* Frameworks */,
@@ -159,9 +159,9 @@
205678942FBF9CBB00251C6B /* Products */ = {
isa = PBXGroup;
children = (
205678932FBF9CBB00251C6B /* MyPass.app */,
205678A22FBF9CBC00251C6B /* MyPassTests.xctest */,
205678AC2FBF9CBC00251C6B /* MyPassUITests.xctest */,
205678932FBF9CBB00251C6B /* KeeVault.app */,
205678A22FBF9CBC00251C6B /* KeeVaultTests.xctest */,
205678AC2FBF9CBC00251C6B /* KeeVaultUITests.xctest */,
2096B431305EC2B200C2F253 /* AutoFill.appex */,
);
name = Products;
@@ -178,9 +178,9 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
205678922FBF9CBB00251C6B /* MyPass */ = {
205678922FBF9CBB00251C6B /* KeeVault */ = {
isa = PBXNativeTarget;
buildConfigurationList = 205678B62FBF9CBC00251C6B /* Build configuration list for PBXNativeTarget "MyPass" */;
buildConfigurationList = 205678B62FBF9CBC00251C6B /* Build configuration list for PBXNativeTarget "KeeVault" */;
buildPhases = (
2056788F2FBF9CBB00251C6B /* Sources */,
205678902FBF9CBB00251C6B /* Frameworks */,
@@ -193,19 +193,19 @@
2096B43C305EC2B200C2F253 /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
205678952FBF9CBB00251C6B /* MyPass */,
205678952FBF9CBB00251C6B /* KeeVault */,
);
name = MyPass;
name = KeeVault;
packageProductDependencies = (
205678DA2FC0EB5200251C6B /* MyPassCore */,
205678DA2FC0EB5200251C6B /* KeeVaultCore */,
);
productName = MyPass;
productReference = 205678932FBF9CBB00251C6B /* MyPass.app */;
productName = KeeVault;
productReference = 205678932FBF9CBB00251C6B /* KeeVault.app */;
productType = "com.apple.product-type.application";
};
205678A12FBF9CBC00251C6B /* MyPassTests */ = {
205678A12FBF9CBC00251C6B /* KeeVaultTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 205678B92FBF9CBC00251C6B /* Build configuration list for PBXNativeTarget "MyPassTests" */;
buildConfigurationList = 205678B92FBF9CBC00251C6B /* Build configuration list for PBXNativeTarget "KeeVaultTests" */;
buildPhases = (
2056789E2FBF9CBC00251C6B /* Sources */,
2056789F2FBF9CBC00251C6B /* Frameworks */,
@@ -217,18 +217,18 @@
205678A42FBF9CBC00251C6B /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
205678A52FBF9CBC00251C6B /* MyPassTests */,
205678A52FBF9CBC00251C6B /* KeeVaultTests */,
);
name = MyPassTests;
name = KeeVaultTests;
packageProductDependencies = (
);
productName = MyPassTests;
productReference = 205678A22FBF9CBC00251C6B /* MyPassTests.xctest */;
productName = KeeVaultTests;
productReference = 205678A22FBF9CBC00251C6B /* KeeVaultTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
205678AB2FBF9CBC00251C6B /* MyPassUITests */ = {
205678AB2FBF9CBC00251C6B /* KeeVaultUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 205678BC2FBF9CBC00251C6B /* Build configuration list for PBXNativeTarget "MyPassUITests" */;
buildConfigurationList = 205678BC2FBF9CBC00251C6B /* Build configuration list for PBXNativeTarget "KeeVaultUITests" */;
buildPhases = (
205678A82FBF9CBC00251C6B /* Sources */,
205678A92FBF9CBC00251C6B /* Frameworks */,
@@ -240,13 +240,13 @@
205678AE2FBF9CBC00251C6B /* PBXTargetDependency */,
);
fileSystemSynchronizedGroups = (
205678AF2FBF9CBC00251C6B /* MyPassUITests */,
205678AF2FBF9CBC00251C6B /* KeeVaultUITests */,
);
name = MyPassUITests;
name = KeeVaultUITests;
packageProductDependencies = (
);
productName = MyPassUITests;
productReference = 205678AC2FBF9CBC00251C6B /* MyPassUITests.xctest */;
productName = KeeVaultUITests;
productReference = 205678AC2FBF9CBC00251C6B /* KeeVaultUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
2096B430305EC2B200C2F253 /* AutoFill */ = {
@@ -266,7 +266,7 @@
);
name = AutoFill;
packageProductDependencies = (
205678DA2FC0EB5200251C6B /* MyPassCore */,
205678DA2FC0EB5200251C6B /* KeeVaultCore */,
);
productName = AutoFill;
productReference = 2096B431305EC2B200C2F253 /* AutoFill.appex */;
@@ -298,7 +298,7 @@
};
};
};
buildConfigurationList = 2056788E2FBF9CBB00251C6B /* Build configuration list for PBXProject "MyPass" */;
buildConfigurationList = 2056788E2FBF9CBB00251C6B /* Build configuration list for PBXProject "KeeVault" */;
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
@@ -308,16 +308,16 @@
mainGroup = 2056788A2FBF9CBB00251C6B;
minimizedProjectReferenceProxies = 1;
packageReferences = (
205678D92FC0EB5200251C6B /* XCLocalSwiftPackageReference "MyPassCore" */,
205678D92FC0EB5200251C6B /* XCLocalSwiftPackageReference "KeeVaultCore" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = 205678942FBF9CBB00251C6B /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
205678922FBF9CBB00251C6B /* MyPass */,
205678A12FBF9CBC00251C6B /* MyPassTests */,
205678AB2FBF9CBC00251C6B /* MyPassUITests */,
205678922FBF9CBB00251C6B /* KeeVault */,
205678A12FBF9CBC00251C6B /* KeeVaultTests */,
205678AB2FBF9CBC00251C6B /* KeeVaultUITests */,
2096B430305EC2B200C2F253 /* AutoFill */,
);
};
@@ -390,12 +390,12 @@
/* Begin PBXTargetDependency section */
205678A42FBF9CBC00251C6B /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 205678922FBF9CBB00251C6B /* MyPass */;
target = 205678922FBF9CBB00251C6B /* KeeVault */;
targetProxy = 205678A32FBF9CBC00251C6B /* PBXContainerItemProxy */;
};
205678AE2FBF9CBC00251C6B /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 205678922FBF9CBB00251C6B /* MyPass */;
target = 205678922FBF9CBB00251C6B /* KeeVault */;
targetProxy = 205678AD2FBF9CBC00251C6B /* PBXContainerItemProxy */;
};
2096B43C305EC2B200C2F253 /* PBXTargetDependency */ = {
@@ -530,7 +530,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = MyPass/MyPass.entitlements;
CODE_SIGN_ENTITLEMENTS = KeeVault/KeeVault.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
@@ -540,6 +540,7 @@
ENABLE_USER_SELECTED_FILES = readonly;
ENTITLEMENTS_REQUIRED = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
INFOPLIST_KEY_NSFaceIDUsageDescription = "Unlock your vault with Face ID.";
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
@@ -556,8 +557,8 @@
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 26.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.mypass;
"PRODUCT_BUNDLE_IDENTIFIER[sdk=xros*]" = org.antiloop222.MyPass;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.keevault;
"PRODUCT_BUNDLE_IDENTIFIER[sdk=xros*]" = org.antiloop222.KeeVault;
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = YES;
SDKROOT = auto;
@@ -579,7 +580,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = MyPass/MyPass.entitlements;
CODE_SIGN_ENTITLEMENTS = KeeVault/KeeVault.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
@@ -589,6 +590,7 @@
ENABLE_USER_SELECTED_FILES = readonly;
ENTITLEMENTS_REQUIRED = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
INFOPLIST_KEY_NSFaceIDUsageDescription = "Unlock your vault with Face ID.";
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
@@ -605,8 +607,8 @@
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 26.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.mypass;
"PRODUCT_BUNDLE_IDENTIFIER[sdk=xros*]" = org.antiloop222.MyPass;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.keevault;
"PRODUCT_BUNDLE_IDENTIFIER[sdk=xros*]" = org.antiloop222.KeeVault;
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = YES;
SDKROOT = auto;
@@ -634,7 +636,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 26.5;
MACOSX_DEPLOYMENT_TARGET = 26.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.mypasstests;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.keevaulttests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
STRING_CATALOG_GENERATE_SYMBOLS = NO;
@@ -645,7 +647,7 @@
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MyPass.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MyPass";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KeeVault.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/KeeVault";
XROS_DEPLOYMENT_TARGET = 26.5;
};
name = Debug;
@@ -661,7 +663,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 26.5;
MACOSX_DEPLOYMENT_TARGET = 26.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.mypasstests;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.keevaulttests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
STRING_CATALOG_GENERATE_SYMBOLS = NO;
@@ -672,7 +674,7 @@
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MyPass.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/MyPass";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KeeVault.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/KeeVault";
XROS_DEPLOYMENT_TARGET = 26.5;
};
name = Release;
@@ -687,7 +689,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 26.5;
MACOSX_DEPLOYMENT_TARGET = 26.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.mypassuitests;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.keevaultuitests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
STRING_CATALOG_GENERATE_SYMBOLS = NO;
@@ -698,7 +700,7 @@
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = MyPass;
TEST_TARGET_NAME = KeeVault;
XROS_DEPLOYMENT_TARGET = 26.5;
};
name = Debug;
@@ -713,7 +715,7 @@
IPHONEOS_DEPLOYMENT_TARGET = 26.5;
MACOSX_DEPLOYMENT_TARGET = 26.5;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.mypassuitests;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.keevaultuitests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
STRING_CATALOG_GENERATE_SYMBOLS = NO;
@@ -724,7 +726,7 @@
SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = MyPass;
TEST_TARGET_NAME = KeeVault;
XROS_DEPLOYMENT_TARGET = 26.5;
};
name = Release;
@@ -732,6 +734,7 @@
2096B43E305EC2B200C2F253 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = AutoFill/AutoFill.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
@@ -749,7 +752,7 @@
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.mypass.autofill;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.keevault.autofill;
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = YES;
SDKROOT = iphoneos;
@@ -769,6 +772,7 @@
2096B43F305EC2B200C2F253 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = AutoFill/AutoFill.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
@@ -786,7 +790,7 @@
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.mypass.autofill;
PRODUCT_BUNDLE_IDENTIFIER = org.antiloop222.keevault.autofill;
PRODUCT_NAME = "$(TARGET_NAME)";
REGISTER_APP_GROUPS = YES;
SDKROOT = iphoneos;
@@ -807,7 +811,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
2056788E2FBF9CBB00251C6B /* Build configuration list for PBXProject "MyPass" */ = {
2056788E2FBF9CBB00251C6B /* Build configuration list for PBXProject "KeeVault" */ = {
isa = XCConfigurationList;
buildConfigurations = (
205678B42FBF9CBC00251C6B /* Debug */,
@@ -816,7 +820,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
205678B62FBF9CBC00251C6B /* Build configuration list for PBXNativeTarget "MyPass" */ = {
205678B62FBF9CBC00251C6B /* Build configuration list for PBXNativeTarget "KeeVault" */ = {
isa = XCConfigurationList;
buildConfigurations = (
205678B72FBF9CBC00251C6B /* Debug */,
@@ -825,7 +829,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
205678B92FBF9CBC00251C6B /* Build configuration list for PBXNativeTarget "MyPassTests" */ = {
205678B92FBF9CBC00251C6B /* Build configuration list for PBXNativeTarget "KeeVaultTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
205678BA2FBF9CBC00251C6B /* Debug */,
@@ -834,7 +838,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
205678BC2FBF9CBC00251C6B /* Build configuration list for PBXNativeTarget "MyPassUITests" */ = {
205678BC2FBF9CBC00251C6B /* Build configuration list for PBXNativeTarget "KeeVaultUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
205678BD2FBF9CBC00251C6B /* Debug */,
@@ -855,16 +859,16 @@
/* End XCConfigurationList section */
/* Begin XCLocalSwiftPackageReference section */
205678D92FC0EB5200251C6B /* XCLocalSwiftPackageReference "MyPassCore" */ = {
205678D92FC0EB5200251C6B /* XCLocalSwiftPackageReference "KeeVaultCore" */ = {
isa = XCLocalSwiftPackageReference;
relativePath = MyPassCore;
relativePath = KeeVaultCore;
};
/* End XCLocalSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
205678DA2FC0EB5200251C6B /* MyPassCore */ = {
205678DA2FC0EB5200251C6B /* KeeVaultCore */ = {
isa = XCSwiftPackageProductDependency;
productName = MyPassCore;
productName = KeeVaultCore;
};
/* End XCSwiftPackageProductDependency section */
};
@@ -7,12 +7,12 @@
<key>AutoFill.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>3</integer>
<integer>0</integer>
</dict>
<key>MyPass.xcscheme_^#shared#^_</key>
<key>KeeVault.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>4</integer>
<integer>1</integer>
</dict>
</dict>
</dict>
@@ -0,0 +1,38 @@
{
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.710",
"green" : "0.396",
"blue" : "0.114",
"alpha" : "1.000"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.890",
"green" : "0.635",
"blue" : "0.357",
"alpha" : "1.000"
}
}
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -3,7 +3,8 @@
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
"size" : "1024x1024",
"filename" : "icon-1024-light.png"
},
{
"appearances" : [
@@ -14,7 +15,8 @@
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
"size" : "1024x1024",
"filename" : "icon-1024-dark.png"
},
{
"appearances" : [
@@ -25,57 +27,68 @@
],
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
"size" : "1024x1024",
"filename" : "icon-1024-tinted.png"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
"size" : "16x16",
"filename" : "icon-mac-16.png"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
"size" : "16x16",
"filename" : "icon-mac-16@2x.png"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
"size" : "32x32",
"filename" : "icon-mac-32.png"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
"size" : "32x32",
"filename" : "icon-mac-32@2x.png"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
"size" : "128x128",
"filename" : "icon-mac-128.png"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
"size" : "128x128",
"filename" : "icon-mac-128@2x.png"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
"size" : "256x256",
"filename" : "icon-mac-256.png"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
"size" : "256x256",
"filename" : "icon-mac-256@2x.png"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
"size" : "512x512",
"filename" : "icon-mac-512.png"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
"size" : "512x512",
"filename" : "icon-mac-512@2x.png"
}
],
"info" : {
Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 964 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

@@ -1,9 +1,4 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
@@ -0,0 +1,38 @@
{
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.980",
"green" : "0.957",
"blue" : "0.925",
"alpha" : "1.000"
}
}
},
{
"idiom" : "universal",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "0.141",
"green" : "0.125",
"blue" : "0.094",
"alpha" : "1.000"
}
}
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -1,12 +1,12 @@
//
// ContentView.swift
// MyPass
// KeeVault
//
// Created by Christophe Vila on 21/05/2026.
//
import SwiftUI
import MyPassCore
import KeeVaultCore
#if os(macOS)
import AppKit
#endif
@@ -22,6 +22,7 @@ struct ContentView: View {
VaultRootView(session: session)
}
}
.background(Color("VaultBackground"))
.onReceive(
NotificationCenter.default.publisher(for: sceneBackgroundNotification)
) { _ in
@@ -6,11 +6,11 @@
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.org.antiloop222.mypass</string>
<string>group.org.antiloop222.keevault</string>
</array>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)org.antiloop222.mypass</string>
<string>$(AppIdentifierPrefix)org.antiloop222.keevault</string>
</array>
</dict>
</plist>
@@ -1,6 +1,6 @@
//
// MyPassApp.swift
// MyPass
// KeeVaultApp.swift
// KeeVault
//
// Created by Christophe Vila on 21/05/2026.
//
@@ -8,7 +8,7 @@
import SwiftUI
@main
struct MyPassApp: App {
struct KeeVaultApp: App {
var body: some Scene {
WindowGroup {
ContentView()
@@ -1,6 +1,6 @@
//
// BiometricAuthService.swift
// MyPass
// KeeVault
//
import LocalAuthentication
@@ -1,6 +1,6 @@
//
// ClipboardService.swift
// MyPass
// KeeVault
//
import Foundation
@@ -1,6 +1,6 @@
//
// FileBookmarkService.swift
// MyPass
// KeeVault
//
import Foundation
@@ -10,7 +10,7 @@ public final class FileBookmarkService {
private static let key = "kdbxBookmark"
private let defaults: UserDefaults
public init(appGroup: String = "group.org.antiloop222.mypass") {
public init(appGroup: String = "group.org.antiloop222.keevault") {
defaults = UserDefaults(suiteName: appGroup) ?? .standard
}
@@ -1,8 +1,8 @@
// MyPass/ViewModels/EntryEditViewModel.swift
// KeeVault/ViewModels/EntryEditViewModel.swift
import Foundation
import Combine
import SwiftUI
import MyPassCore
import KeeVaultCore
@MainActor
final class EntryEditViewModel: ObservableObject {
@@ -20,7 +20,7 @@ final class EntryEditViewModel: ObservableObject {
private let existingEntry: Entry?
/// `groupId` is the target group for a new entry, or the entry's current group when
/// editing (shown read-only in that case -- MyPass doesn't support re-parenting an
/// editing (shown read-only in that case -- KeeVault doesn't support re-parenting an
/// existing entry to a different group yet).
init(session: VaultSession, groupId: UUID, existing: Entry? = nil) {
self.session = session
@@ -1,6 +1,6 @@
import Foundation
import Combine
import MyPassCore
import KeeVaultCore
@MainActor
final class GroupFilterViewModel: ObservableObject {
@@ -16,11 +16,11 @@ final class GroupFilterViewModel: ObservableObject {
self.session = session
}
func isSelected(_ group: MyPassCore.Group) -> Bool {
func isSelected(_ group: KeeVaultCore.Group) -> Bool {
selectedGroupIds.contains(group.id)
}
func toggle(_ group: MyPassCore.Group) {
func toggle(_ group: KeeVaultCore.Group) {
guard let root = session.database?.root else { return }
selectedGroupIds = GroupSelection.toggling(group.id, in: root, current: selectedGroupIds)
lastToggledGroupId = selectedGroupIds.isEmpty ? nil : group.id
@@ -1,11 +1,11 @@
//
// UnlockViewModel.swift
// MyPass
// KeeVault
//
import Foundation
import Combine
import MyPassCore
import KeeVaultCore
@MainActor
final class UnlockViewModel: ObservableObject {
@@ -24,7 +24,7 @@ final class UnlockViewModel: ObservableObject {
init(
session: VaultSession,
bookmarkService: FileBookmarkService = .init(),
keychainStore: KeychainStore = .init(accessGroup: "F2KB6W8N4R.org.antiloop222.mypass"),
keychainStore: KeychainStore = .init(accessGroup: "F2KB6W8N4R.org.antiloop222.keevault"),
biometricService: BiometricAuthService = .init()
) {
self.session = session
@@ -44,7 +44,7 @@ final class UnlockViewModel: ObservableObject {
isUnlocking = true
errorMessage = nil
do {
try await biometricService.authenticate(reason: "Unlock MyPass")
try await biometricService.authenticate(reason: "Unlock KeeVault")
let storedPassword = try keychainStore.load(for: keychainAccount)
let url = try bookmarkService.resolveURL()
defer { bookmarkService.stopAccess(url: url) }
@@ -1,7 +1,7 @@
// MyPass/ViewModels/VaultViewModel.swift
// KeeVault/ViewModels/VaultViewModel.swift
import Foundation
import Combine
import MyPassCore
import KeeVaultCore
@MainActor
final class VaultViewModel: ObservableObject {
@@ -1,11 +1,11 @@
//
// EntryDetailView.swift
// MyPass
// KeeVault
//
import SwiftUI
import Combine
import MyPassCore
import KeeVaultCore
struct EntryDetailView: View {
let entry: Entry
@@ -1,6 +1,6 @@
// MyPass/Views/EntryEditView.swift
// KeeVault/Views/EntryEditView.swift
import SwiftUI
import MyPassCore
import KeeVaultCore
struct EntryEditView: View {
@ObservedObject var vm: EntryEditViewModel
@@ -1,6 +1,6 @@
// MyPass/Views/EntryListView.swift
// KeeVault/Views/EntryListView.swift
import SwiftUI
import MyPassCore
import KeeVaultCore
struct EntryListView: View {
@ObservedObject var vm: VaultViewModel
@@ -23,7 +23,9 @@ struct EntryListView: View {
offsets.map { vm.displayedEntries[$0] }.forEach(vm.deleteEntry)
}
}
.navigationTitle("MyPass")
.scrollContentBackground(.hidden)
.background(Color("VaultBackground"))
.navigationTitle("KeeVault")
.searchable(text: $vm.searchQuery, prompt: "Search entries…")
.toolbar {
ToolbarItem(placement: .primaryAction) {
@@ -1,9 +1,9 @@
import SwiftUI
import MyPassCore
import KeeVaultCore
struct GroupFilterView: View {
@ObservedObject var vm: GroupFilterViewModel
let rootGroup: MyPassCore.Group
let rootGroup: KeeVaultCore.Group
var body: some View {
List {
@@ -12,24 +12,25 @@ struct GroupFilterView: View {
}
GroupFilterNode(group: rootGroup, vm: vm)
}
.scrollContentBackground(.hidden)
.background(Color("VaultBackground"))
.navigationTitle("Groups")
}
}
private struct GroupFilterNode: View {
let group: MyPassCore.Group
let group: KeeVaultCore.Group
@ObservedObject var vm: GroupFilterViewModel
var depth: Int = 0
var body: some View {
if group.subgroups.isEmpty {
// A plain SwiftUI.Group (not a container view) flattens its children into
// separate List rows, so the whole subtree renders always-expanded --
// no DisclosureGroup, no tap-to-reveal -- active filters are visible at a glance.
SwiftUI.Group {
row
} else {
DisclosureGroup {
ForEach(group.subgroups) { sub in
GroupFilterNode(group: sub, vm: vm)
}
} label: {
row
ForEach(group.subgroups) { sub in
GroupFilterNode(group: sub, vm: vm, depth: depth + 1)
}
}
}
@@ -45,5 +46,6 @@ private struct GroupFilterNode: View {
}
}
.buttonStyle(.plain)
.padding(.leading, CGFloat(depth) * 16)
}
}
@@ -1,11 +1,11 @@
//
// UnlockView.swift
// MyPass
// KeeVault
//
import SwiftUI
import UniformTypeIdentifiers
import MyPassCore
import KeeVaultCore
struct UnlockView: View {
@ObservedObject var vm: UnlockViewModel
@@ -16,7 +16,7 @@ struct UnlockView: View {
Image(systemName: "lock.shield.fill")
.font(.system(size: 64))
.foregroundStyle(.tint)
Text("MyPass")
Text("KeeVault")
.font(.largeTitle.bold())
if vm.hasVault {
@@ -0,0 +1,14 @@
<?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>SchemeUserState</key>
<dict>
<key>KeeVaultCore.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
</dict>
</dict>
</plist>
@@ -2,24 +2,24 @@
import PackageDescription
let package = Package(
name: "MyPassCore",
name: "KeeVaultCore",
platforms: [.iOS(.v17), .macOS(.v14)],
products: [
.library(name: "MyPassCore", targets: ["MyPassCore"]),
.library(name: "KeeVaultCore", targets: ["KeeVaultCore"]),
],
dependencies: [
.package(path: "../Vendor/KeePassKit"),
],
targets: [
.target(
name: "MyPassCore",
name: "KeeVaultCore",
dependencies: [
.product(name: "KeePassKit", package: "KeePassKit"),
]
),
.testTarget(
name: "MyPassCoreTests",
dependencies: ["MyPassCore"],
name: "KeeVaultCoreTests",
dependencies: ["KeeVaultCore"],
resources: [.copy("Fixtures")]
),
]
@@ -1,7 +1,7 @@
import Foundation
/// Maps KeePass's standard icon palette (indices 0-68) to an approximate SF Symbol.
/// This is a best-effort visual match, not the actual KeePass icon artwork -- MyPass's
/// This is a best-effort visual match, not the actual KeePass icon artwork -- KeeVault's
/// data model only stores the numeric iconIndex, not custom icon images.
public enum KeePassIconMapper {
private static let symbolsByIndex: [Int: String] = [
@@ -3,7 +3,7 @@ import KeePassKit
enum KDBXMapper {
// MARK: - KeePassKit MyPassCore
// MARK: - KeePassKit KeeVaultCore
static func database(from tree: KPKTree) -> KDBXDatabase {
let meta = DatabaseMetadata(
@@ -67,7 +67,7 @@ enum KDBXMapper {
)
}
// MARK: - MyPassCore KeePassKit
// MARK: - KeeVaultCore KeePassKit
static func tree(from db: KDBXDatabase) -> KPKTree {
let tree = KPKTree()
@@ -129,7 +129,7 @@ enum KDBXMapper {
var components = URLComponents()
components.scheme = "otpauth"
components.host = "totp"
components.path = "/MyPass"
components.path = "/KeeVault"
components.queryItems = [
URLQueryItem(name: "secret", value: config.secret),
URLQueryItem(name: "period", value: String(config.period)),
@@ -5,7 +5,7 @@ public struct KeychainStore {
private let accessGroup: String
private let service: String
public init(accessGroup: String, service: String = "org.antiloop222.mypass") {
public init(accessGroup: String, service: String = "org.antiloop222.keevault") {
self.accessGroup = accessGroup
self.service = service
}
@@ -1,5 +1,5 @@
import XCTest
@testable import MyPassCore
@testable import KeeVaultCore
final class CredentialMatcherTests: XCTestCase {
func makeEntry(url: String) -> Entry {
@@ -1,5 +1,5 @@
import XCTest
@testable import MyPassCore
@testable import KeeVaultCore
final class GroupSelectionTests: XCTestCase {
private func makeSampleTree() -> (root: Group, work: Group, email: Group, personal: Group) {
@@ -1,5 +1,5 @@
import XCTest
@testable import MyPassCore
@testable import KeeVaultCore
final class GroupTreeTests: XCTestCase {
private func makeSampleTree() -> (root: Group, work: Group, email: Group) {
@@ -1,5 +1,5 @@
import XCTest
@testable import MyPassCore
@testable import KeeVaultCore
final class KDBXDocumentTests: XCTestCase {
var fixtureURL: URL!
@@ -1,5 +1,5 @@
import XCTest
@testable import MyPassCore
@testable import KeeVaultCore
final class KeePassIconMapperTests: XCTestCase {
func test_knownIndex_returnsMappedSymbol() {
@@ -1,5 +1,5 @@
import XCTest
@testable import MyPassCore
@testable import KeeVaultCore
final class ProtectedStringTests: XCTestCase {
func test_reveal_returnsOriginalValue() {
@@ -1,5 +1,5 @@
import XCTest
@testable import MyPassCore
@testable import KeeVaultCore
final class TOTPGeneratorTests: XCTestCase {
// RFC 6238 Section 8 test vectors for SHA-1
@@ -1,13 +1,13 @@
//
// MyPassTests.swift
// MyPassTests
// KeeVaultTests.swift
// KeeVaultTests
//
// Created by Christophe Vila on 21/05/2026.
//
import Testing
struct MyPassTests {
struct KeeVaultTests {
@Test func example() async throws {
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
@@ -1,13 +1,13 @@
//
// MyPassUITests.swift
// MyPassUITests
// KeeVaultUITests.swift
// KeeVaultUITests
//
// Created by Christophe Vila on 21/05/2026.
//
import XCTest
final class MyPassUITests: XCTestCase {
final class KeeVaultUITests: XCTestCase {
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
@@ -1,13 +1,13 @@
//
// MyPassUITestsLaunchTests.swift
// MyPassUITests
// KeeVaultUITestsLaunchTests.swift
// KeeVaultUITests
//
// Created by Christophe Vila on 21/05/2026.
//
import XCTest
final class MyPassUITestsLaunchTests: XCTestCase {
final class KeeVaultUITestsLaunchTests: XCTestCase {
override class var runsForEachTargetApplicationUIConfiguration: Bool {
true