feat(connections): import and export connections on iOS#1738
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2c63fb21b4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| port: ssh.port, | ||
| username: ssh.username, | ||
| authMethod: ssh.authMethod.rawValue, | ||
| privateKeyPath: PathPortability.contractHome(ssh.privateKeyPath ?? ""), |
There was a problem hiding this comment.
Preserve pasted SSH private keys during export
When an iOS connection uses pasted private-key auth, the key material is stored separately in Keychain under com.TablePro.sshkeydata.<id> and IOSSSHProvider reloads it before connecting; this export only serializes privateKeyPath (which is empty for pasted keys), and the encrypted credentials path only includes passwords/passphrases. Re-importing even an encrypted export of such a connection therefore creates .privateKey auth with no key, so SSH tunnel creation fails with “No private key provided.”
Useful? React with 👍 / 👎.
| } | ||
| } | ||
|
|
||
| let safeMode = exportable.safeModeLevel.flatMap { SafeModeLevel(rawValue: $0) } ?? .off |
There was a problem hiding this comment.
Map imported safe-mode values instead of dropping them
When importing macOS exports with safeModeLevel values such as alert, alertFull, safeMode, or safeModeFull, this direct lookup uses the iOS enum (off, confirmWrites, readOnly), so those protective modes fall through to .off. The imported connection silently loses write-confirmation protection; map the macOS raw values to .confirmWrites or another supported iOS protection instead of defaulting them off.
Useful? React with 👍 / 👎.
| case "sshagent", "agent", "ssh agent": return .sshAgent | ||
| case "keyboardinteractive", "keyboard interactive": return .keyboardInteractive |
There was a problem hiding this comment.
Avoid importing unsupported SSH auth methods on iOS
When a macOS .tablepro export uses SSH Agent or Keyboard Interactive auth, these cases preserve that value on iOS, but SSHTunnelFactory.create only handles .password and .privateKey and throws for the default branch. That means the imported connection cannot connect on iOS; warn/skip these auth modes or map them to a supported editable state instead of saving an unsupported configuration.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 532fd66e45
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return ConnectionImportAnalyzer.analyze( | ||
| envelope, | ||
| existingConnections: candidates, | ||
| registeredTypeIds: Set(DatabaseType.allKnownTypes.map(\.rawValue)), |
There was a problem hiding this comment.
Validate imports against iOS-supported drivers
When a macOS export contains a built-in type that iOS does not actually ship a driver for (for example MongoDB, ClickHouse, Oracle, etc.), this uses DatabaseType.allKnownTypes, so the analyzer marks the item as ready. I checked IOSDriverFactory.createDriver, and it only handles SQLite, DuckDB, MySQL/MariaDB, PostgreSQL/Redshift, Redis, and SQL Server before throwing driverNotFound; these imported connections therefore appear importable but cannot connect on iOS. Use the iOS driver-supported type list for this validation or block unsupported types during import.
Useful? React with 👍 / 👎.
| host: host, | ||
| port: exportable.port, | ||
| username: exportable.username, | ||
| database: exportable.database, |
There was a problem hiding this comment.
Preserve Redis DB index when importing to iOS
When importing a macOS Redis export, the selected logical database is carried in redisDatabase while database is often empty, but this builds the iOS connection from only exportable.database. The iOS Redis path later derives the DB with Int(connection.database) ?? 0, so a Redis connection exported with redisDatabase: 5 silently connects to DB 0 after import; populate the iOS database string from exportable.redisDatabase for Redis imports.
Useful? React with 👍 / 👎.
…export tests after merge
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 65d4dcb967
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| sshConfiguration = SSHConfiguration( | ||
| host: ssh.host, | ||
| port: ssh.port ?? 22, | ||
| username: ssh.username, | ||
| authMethod: sshAuthMethod(from: ssh.authMethod), |
There was a problem hiding this comment.
Warn before dropping SSH TOTP settings
When importing a macOS export whose SSH config uses TOTP (for example totpMode: autoGenerate with a saved totpSecret in the encrypted credentials), this iOS constructor drops the exported TOTP fields, and restoreCredentials only restores password/SSH password/key passphrase. I checked the iOS SSHConfiguration/SSHTunnelFactory path and there is no TOTP fallback, so these imported password/private-key SSH connections show as importable but fail against servers that require the second factor; the import should warn/skip or map to a supported editable state.
Useful? React with 👍 / 👎.
| jumpHosts: (ssh.jumpHosts ?? []).map { | ||
| SSHJumpHost(host: $0.host, port: $0.port ?? 22, username: $0.username) | ||
| } |
There was a problem hiding this comment.
Reject unsupported SSH jump-host imports
When a macOS .tablepro export relies on a jump host/bastion, this preserves a jumpHosts array in the imported iOS model, but I checked TableProMobile/SSH/SSHTunnelFactory.swift and tunnel creation never reads config.jumpHosts before connecting to config.host. The imported connection therefore attempts to reach the final SSH host directly and fails in networks where the bastion is required; warn/skip these imports or implement jump-host tunneling instead of marking them usable.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8d7847a9a6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| clientCertificatePath: expandedPath(ssl.clientCertificatePath), | ||
| clientKeyPath: expandedPath(ssl.clientKeyPath) |
There was a problem hiding this comment.
Warn before importing unsupported SSL client certs
When a macOS export uses mutual TLS, these client certificate/key paths are preserved and the item is marked importable, but the iOS connection path never uses them: DriverSSLConfiguration only carries the CA path and the iOS drivers do not pass a client cert/key to the native libraries. Those imports therefore fail against servers that require client certificates while the preview shows them as usable; warn/skip these configs or implement client-certificate handling before saving them.
Useful? React with 👍 / 👎.
| host: host, | ||
| port: exportable.port, | ||
| username: exportable.username, | ||
| database: exportable.database, |
There was a problem hiding this comment.
Don't import file databases as bare paths
For SQLite/DuckDB imports, this saves the exported absolute database path directly. Normal iOS file connections either copy SQLite files into Documents or save a security-scoped DuckDB bookmark; an imported ~/Documents/foo.db or macOS /Users/.../foo.db path has neither, so SQLite/DuckDB will open a missing/inaccessible path and can fail or create an empty database instead of the original file. File-based imports should require the user to choose/copy the database file or at least be blocked with a warning.
Useful? React with 👍 / 👎.
What
Brings connection import (and export) to the iPhone app. A TestFlight user asked for a way to import connections on iOS; the Mac app already had a full import/export system, but iOS had none of it.
Approach
The serialization, crypto, and import-analysis logic lived inside the macOS app target. Rather than duplicate it on iOS (which would let a crypto fix drift between platforms), it moves into a new shared SPM target both apps use.
TableProImportSPM target (Packages/TableProCore): the.tableproenvelope/exportable types,ConnectionExportCrypto(AES-256-GCM, PBKDF2 600k), and pureConnectionImportAnalyzer+ConnectionImportDecoder. No AppKit; builds on macOS and iOS.ImportItemStatus.duplicateassociated value to drop the macOS-type dependency. All callers and tests updated in the same commit..fileImporterfrom a new "more" menu, a nativeMobileConnectionImportSheet(preview, duplicate resolution, passphrase prompt for encrypted files),IOSConnectionImportService/IOSConnectionExportService, share-sheet export with an optional passphrase-encrypted credentials file, and.tableproopen-in from Files/AirDrop viaUTExportedTypeDeclarations+CFBundleDocumentTypesandonOpenURL.Secrets stay excluded by default; including passwords requires a passphrase that encrypts the file, matching Apple's Keychain guidance and the existing macOS behavior.
Tests
TableProImportTests(15): crypto round-trip including wrong passphrase and corrupt header, envelope round-trip, analyzer duplicate/warning logic, path portability.IOSConnectionImportServiceTests(4): credential restore key format and mapped-indices-only, suggested filename.--strictclean.Notes
TableProTeststarget has a pre-existing local link failure inOracleConnectionErrorTests(needs the OracleNIO fork built); unrelated to this change. The edited macOS import tests compile.