Release 1.9.1 - #533
Draft
terrerox wants to merge 68 commits into
Draft
Conversation
terrerox
marked this pull request as draft
July 13, 2026 17:37
| android:authorities="com.internxt.cloud.documents" | ||
| android:exported="true" | ||
| android:grantUriPermissions="true" | ||
| android:permission="android.permission.MANAGE_DOCUMENTS" |
| kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock, | ||
| kSecValueData as String: value, | ||
| ] | ||
| SecItemAdd(query as CFDictionary, nil) |
Adds a pure-Kotlin HTTP client that talks directly to the Drive and Bridge APIs so the SAF DocumentsProvider can fetch folder contents and download links without the React Native bridge. Covers list/create/rename/move/trash on Drive (Bearer auth) and getDownloadLinks on Bridge (Basic auth with sha256(userId).hex derivation). Typed errors for 401/404/other/network; MockWebServer tests for parsing, auth headers, gateway-required headers, and error mapping.
- Wire AuthConfig.clientName/clientVersion through
BuildConfig.INTERNXT_CLIENT_NAME and BuildConfig.INTERNXT_CLIENT_VERSION,
populated by app/build.gradle from package.json. package.json is now the
single source of truth for the internxt-client/internxt-version headers.
- Extract JSON helpers (orEmpty, map, optStringOrNull, optLongFlexible)
from InternxtApiClient into JsonExtensions.kt; cover each branch in a
new JsonExtensionsTest.
- Rename InternxtApiClient.execute -> executeApiRequest.
- Expand InternxtApiClientTest: listFolderFolders, createFolder, null
optional fields, size given as a string, and 5xx -> ApiError. Add an
enqueueJson helper to cut response-stub boilerplate.
- Add @TamaraFinogina as CODEOWNER for the new documents/crypto/ directory.
…onstants in InternxtApiClientTest
…HttpClient configuration
InternxtDocumentsProvider.queryRoots() now reads credentials from EncryptedSharedPreferences via a new InternxtAuthManager and returns an empty cursor when no user is signed in, so "Internxt Drive" only appears in the system file picker while the app has an active session; credentials are written by a new RN bridge (InternxtAuthCredentialsModule) from signInThunk and refreshTokensThunk and cleared from signOutThunk, with both paths firing contentResolver.notifyChange(rootsUri) so the picker refreshes without restarting the app, while queryRoots() itself stays strictly synchronous and local-only to avoid freezing the system picker.
…t folder UUID synchronization
- Implement queryChildDocuments to paginate folders + files for a parent UUID
- Implement queryDocument to resolve real metadata via folders/{uuid}/meta
and files/{uuid}/meta, with a UUID-named placeholder fallback for
offline / transient failures
- Add InternxtApiClient.getFolder / getFile (404 → null) plus tests
- Introduce DocumentRowBuilder (column-keyed rows) and MimeTypes
(hand-rolled table + Android MimeTypeMap fallback) with tests
- Surface InternxtApiException + null auth-config via Log.w so silent
failures are no longer invisible
- Fix auth slice to sync newToken (not token) to native credentials so
the documents provider authenticates against drive endpoints
- Override renameDocument, moveDocument, and deleteDocument in InternxtDocumentsProvider so SAF surfaces the corresponding row actions.
- Surface FLAG_SUPPORTS_RENAME | FLAG_SUPPORTS_DELETE | FLAG_SUPPORTS_MOVE on file and folder rows; keep root and placeholder rows mutation-free.
- Cache item kind (file vs folder) per UUID so mutations resolve their endpoint without an extra round-trip on the happy path.
- Notify affected child-document URIs after each mutation so the picker refreshes without manual reload.
- Fix InternxtApiClient.renameFile / renameFolder to match the SDK: PUT /{files|folders}/{uuid}/meta with { plainName }, void response.
- Await clearCredentials in signOutThunk so the SAF root is hidden immediately after logout instead of lingering until documentsui refreshes.
…document operations
…sh functionalities
- Override renameDocument, moveDocument, and deleteDocument in InternxtDocumentsProvider so SAF surfaces the corresponding row actions.
- Surface FLAG_SUPPORTS_RENAME | FLAG_SUPPORTS_DELETE | FLAG_SUPPORTS_MOVE on file and folder rows; keep root and placeholder rows mutation-free.
- Cache item kind (file vs folder) per UUID so mutations resolve their endpoint without an extra round-trip on the happy path.
- Notify affected child-document URIs after each mutation so the picker refreshes without manual reload.
- Fix InternxtApiClient.renameFile / renameFolder to match the SDK: PUT /{files|folders}/{uuid}/meta with { plainName }, void response.
- Await clearCredentials in signOutThunk so the SAF root is hidden immediately after logout instead of lingering until documentsui refreshes.
…and enhance error handling
…rivation and simplify methods
…with new HttpClients
…lean up test cases
Replace CompletableFuture.get(), Call.execute() and the manual AtomicReference + setOnCancelListener cancellation plumbing with kotlinx-coroutines across the native DocumentsProvider stack: crypto, download and upload now suspend via Call.await()/CallAwait and CryptoServiceAwait, and openDocument bridges to coroutines through runBlockingIo (BlockingIo) instead of a plain runBlocking, surfacing cancellation as FileNotFoundException. Adds kotlinx-coroutines-android and kotlinx-coroutines-test to android/app/build.gradle and JVM unit tests for BlockingIo, CryptoServiceAwait, EncryptedFileDownloader and EncryptedFileUploader. NOTE: a separate, unrelated change by the maintainer lives in the same file (InternxtDocumentsProvider.kt) and could not be split out because interactive staging (git add -p) is unavailable and editing source is out of scope for the git-manager: refresh() now triggers a background revalidateChildren (new revalidate/fetchAllRows helpers and the FolderLoad.isRevalidating flag) instead of invalidateChildren. It is bundled here intentionally; see progress/git_android_coroutines_migration.md. Refs: PB-6282
…toServiceAwaitTest
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sync auth credentials to a shared App Group Keychain so the File Provider extension can read them; register the com.internxt.drive domain on login and call removeAllDomains on logout so the provider appears/disappears in Files.app. Bump InternxtFileProvider MARKETING_VERSION 1.0 -> 1.9.0 (Debug+Release) so the extension version matches the host or iOS won't load it. Device-verified on a real iPhone. Refs: PB-5920
… adjust accessibility for background reads
The File Provider extension needs the Drive API base URL to build authenticated requests from the App Group keychain. Add a dedicated shared key so it can be read alongside the existing auth token.
Replace the placeholder enumerator with real Drive folder browsing: paginate folders then files for a container, build FileProviderItem metadata (name, type, size, dates, capabilities) from Drive responses, and resolve identifiers via a typed folder/file id codec. Add a DriveAPIFactory that constructs an authenticated DriveAPI from the shared App Group keychain, and wire the new sources into the extension target.
Implement item(for:) so the system can resolve any identifier to a FileProviderItem: return the root container item, decode folder/file identifiers and fetch their metadata from the Drive API, and map 401 responses to NSFileProviderError.notAuthenticated so the system can re-request credentials.
Persist the Drive API base URL in the App Group keychain when credentials are written, so the File Provider extension can build authenticated Drive requests. Add a wrapper test asserting the native module receives driveBaseUrl.
Add FileProviderDomainManager.signalEnumeration to notify the working set enumerator, and call it once the File Provider domain is registered so the Files app refreshes Drive contents right after credentials change. Signal failures are logged and ignored to avoid blocking login.
Adds NetworkFacadeFactory and SharedKeychainCredentials to the File Provider extension so items can be downloaded from the network and decrypted on demand. Persists bridgeBaseUrl to the shared keychain and JSON-decodes bridgeUser/userId so the extension reads matching credentials.
Implement the write path in the NSFileProviderReplicatedExtension so the Files.app can create folders and upload files to Drive. createItem routes folder creation to the Drive API and file uploads through InternxtSwiftCore encryption plus network upload, then registers the file and returns the created NSFileProviderItem. Adds rename support via modifyItem and friendly non-crashing errors for offline/unauthenticated/generic failures.
…FileProviderError Revert the FriendlyError helper and fileProviderError factory; surface plain NSFileProviderError values while keeping the same error codes (noSuchItem, notAuthenticated, serverUnreachable).
Extract upload, download, mutation, and error-mapping logic out of the monolithic FileProviderExtension into dedicated services so the extension becomes a thin coordinator, easing testability and maintenance ahead of move/trash/versioning work.
Introduce a host-less InternxtFileProviderTests target covering the pure NSFileProviderError mapping logic now isolated in FileProviderErrorMapper.
Implement modifyItem move/rename and deleteItem-to-backend-trash in the File Provider extension. Item capabilities use .allowsDeleting (not .allowsTrashing) so the system routes deletes through deleteItem, which maps to the Drive backend trash endpoint instead of a local-only trash.
Add a per-folder snapshot/diff change-feed in the File Provider extension so working-set enumeration surfaces upload, create-folder, move, rename, trash and restore as changes. SyncAnchorStore persists the per-domain anchor; FileProviderModule exposes a native bridge so the host app can signal the enumerator on RN mutations.
Add a cross-platform InternxtSignalingModule with a single notifyParentChanged(parentUuid) bridge (symmetric to Android) and call it from the upload, create-folder, move, rename, trash and restore paths so the native File Provider change-feed refreshes the affected folder.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


No description provided.