Skip to content

WIP: Next Prod Release Candidate#779

Draft
prathieshna wants to merge 304 commits intonextfrom
NEXT-WITHOUT-STORACHA
Draft

WIP: Next Prod Release Candidate#779
prathieshna wants to merge 304 commits intonextfrom
NEXT-WITHOUT-STORACHA

Conversation

@prathieshna
Copy link
Copy Markdown

•⁠ ⁠Bug Fixes Reported by QA
•⁠ ⁠⁠Security Fixes based on the document
•⁠ ⁠⁠Storacha Removed
•⁠ ⁠⁠C2PA chnages with additional data similar to Proofmode Legacy
•⁠ ⁠⁠TOR - cTOR based

Prathieshna Vekneswaran added 30 commits October 6, 2025 18:40
App version bump to 4.0.4
- Improved Storacha disclaimer with a link to learn more.
- Refined various UI text and labels for clarity and consistency.
- Added user-friendly error messages for upload failures.
- Renamed "Manage DIDs" to "Manage Accounts" for better user understanding.
Expanded file type support to include PDFs and various other document formats (doc, docx, txt, etc.).

Refactored the file selection handling in `StorachaMediaFragment` to use a single, unified `handleMedia` function for all file types, removing redundant type-specific handlers.
- Implemented back press blocking during file uploads.
- Fixed an issue causing upload success/error dialogs to reappear.
- Added cleanup for temporary and CAR files after successful uploads.
- Refined the upload retry logic to regenerate CAR files.
- The "Manage Access" menu item is now disabled during uploads.
The login button is now disabled by default. It becomes enabled only when the user enters a valid email format in the email field.
The error message on the email field is cleared as the user starts typing.
Storacha Login:
- Added a loading indicator for the login process.
- Disabled the login button while authentication is in progress.

Storacha DID Management:
- Implemented validation for DID format (`did:key:z...`) on the DID Access screen.
- Added checks to prevent adding duplicate DIDs for a space.
- The DID scanner now validates the format and checks for duplicates.
- Added extensive unit tests for `Ed25519Utils.isValidDid`.
Introduced `StorachaHelper` to centralize logic for determining user access to Storacha features. This helper checks if a user has logged-in accounts or has joined any spaces.

Key changes:
- Replaced direct `DidManager` checks in `MainActivity` and `StorachaFragment` with the new `StorachaHelper.shouldEnableStorachaAccess()` method.
- Added logic in `StorachaBrowseSpacesFragment` to count and store the number of joined spaces using `StorachaHelper`.
- The "My Spaces" button and the Storacha service in the space list are now enabled if the user is logged in or has joined at least one space.
- Replaced the legacy `Picker.takePhoto` with `Picker.takePhotoModern`.
- Enabled camera permission check before launching the camera in `MainActivity` and `PreviewActivity`.
Updated version to 4.0.6
Refactored button bars and layouts for consistency in:
- StorachaLoginFragment
- StorachaClientQRFragment
- StorachaAccountDetailsFragment
- StorachaDIDAccessFragment

Moved `StorachaAccount.kt` to a new `model` subpackage.
Instead of loading the entire CAR file into a `ByteArray` in memory, this change modifies the upload process to stream the file directly from disk. This significantly reduces memory usage, especially for large files.

The `CarFileCreator` now writes the generated CAR file directly to a temporary file instead of returning a byte array. `BridgeUploader` and `StorachaMediaViewModel` have been updated to work with this new `File`-based approach.

Additionally, temporary CAR files are now cleaned up after a successful upload, on retry, or when the view is destroyed.
- Optimized CAR file creation to stream large files and write blocks directly to a temporary file, significantly reducing memory usage.
- Introduced a separate OkHttpClient for S3 uploads without logging to prevent OutOfMemoryError on large file uploads.
- Increased S3 client timeouts to 5 minutes to better handle large file transmissions.
Cleans up any temporary or CAR files from a previously failed upload before starting a new one in `StorachaMediaFragment`.
updated backgroundTint to use button_color
This commit introduces a comprehensive session management system for Storacha to handle expired or invalid sessions gracefully.

Key changes include:
*   Added a centralized `SessionManager` to validate sessions and automatically remove invalid accounts.
*   Implemented an `AuthInterceptor` to catch 401/403 errors and trigger session expiration flows.
*   Introduced common `showSessionExpiredDialog()` methods in `BaseFragment` for consistent user feedback.
*   In ViewModels, added `sessionExpired` LiveData to notify fragments of authentication failures, allowing them to display the appropriate dialog.
*   Updated the "Browse Spaces" screen to allow users to continue browsing delegated spaces even after their session expires.
*   Minor code cleanup and version bump to 4.0.7.
- Added real-time DID format validation on the input field.
- The "Next" button is now enabled/disabled based on the validity of the DID format.
- A loading indicator with the text "Adding DID…" is now displayed while the DID is being processed.
added camera support to storacha
fixed storacha file upload from gallery
- Made entire account row clickable in Storacha browse accounts screen
- Styled "no media" and "no DID" empty state messages
- Improved Storacha login screen UI and added external link for account creation
- Updated various string resources for clarity and punctuation
- Refined styling across Storacha screens, including buttons, cards, and text
This commit removes all code related to the Google Drive integration, including activities, fragments, conduits, layouts, and related assets.

Other changes include:
- Upgrade Gradle to 9.2.0
- Add custom CameraX implementation for photo and video
- Add in-app update coordinator
- UI/UX improvements to login, media preview, and selection
- Various bug fixes and code cleanup
- Optimized camera image handling to use the existing cached file directly instead of creating a copy, preventing 0-byte file errors.
- Introduced `getOutputMediaFileByCacheNoTimestamp` to create temporary files with predictable names.
- Refactored `StorachaMediaFragment` to correctly handle URIs from both the camera and the gallery.
Prathieshna Vekneswaran and others added 21 commits April 27, 2026 16:19
…tivity checks before starting uploads.

### Core Changes
- **New `UploadGate` Utility**: Introduced a central component to validate network conditions (Wi-Fi requirement) and Tor status before proceeding with uploads. It includes specific logic to skip Tor checks for DWeb (Snowbird) storage.
- **Improved Background Resumption**: Added `checkIfQueued` to `UploadGate` to prevent spurious connectivity dialogs when the app resumes if the upload queue is empty.
- **Enhanced Error Handling in `WebDavConduit`**: Added explicit checks for file existence (ENOENT) before upload. If a file is missing, the evidence record is now deleted to prevent the queue from getting stuck in a permanent error state.
- **Upload Cancellation Fix**: Updated `Conduit` to reset cancelled uploads to a `QUEUED` status and clear transient UI progress, ensuring they can be retried in the next session.
- **ProGuard Optimization**: Added `-optimizations !class/merging/*` to prevent R8 from merging `CleanInsights` configuration classes, which previously caused Moshi serialization failures.

### UI and Integration
- Integrated `UploadGate` into `HomeActivity`, `HomeViewModel`, `UploadManagerViewModel`, and `PreviewMediaViewModel` to wrap upload triggers.
- Added `NetworkUtils.isOnWifi` helper.
- Added localized strings for Wi-Fi and Tor connectivity warnings.
- Registered `UploadGate` in `TorModule` for dependency injection.
- Add `REVIEW_MEDIA_SAVED` constant to `NavigationResultKeys`.
- Trigger `REVIEW_MEDIA_SAVED` event in `ReviewMediaViewModel` after successfully saving media.
- Observe `REVIEW_MEDIA_SAVED` in `PreviewMediaViewModel` to reset selection state (clear `selectedIds` and `selectionCount`) when media is saved.
Updated and synchronized `strings.xml` for multiple languages:
- Added new translations and corrected existing strings for Arabic, Spanish, Farsi, French, Russian, Turkish, and Ukrainian.
- Added comprehensive new localization support for Belarusian, Kurdish, Polish, Portuguese (Brazil), Chinese (Simplified), Chinese (Traditional), and Chinese (Hong Kong).
- Synchronized Transifex metadata and formatting across resource files.
* Removed redundant locale directories `values-pt_BR`, `values-zh-Hans`, `values-zh_HK`, and `values-zh_TW`.
* Added and synchronized translation files for `values-pt-rBR`, `values-uk`, `values-zh-rHK`, `values-zh-rTW`, and `values-b+zh+Hans`.
* Updated `IaConduit.kt` to include exponential backoff retries for 503 errors during Internet Archive uploads.
* Refactored `WebDavConduit.kt` to improve chunked upload reliability and metadata sequencing.
* Integrated C2pa provenance and metadata collection into `CameraViewModel` for camera captures.
* Updated `UploadGate` and `UploadService` to better respect TOR connectivity and WiFi-only settings.
* Improved error handling and retry logic in `UploadManagerViewModel`.
* Cleaned up `provider_paths.xml` to limit FileProvider exposure to specific app directories.
* Passed `VaultType` through navigation and picker components to conditionally apply provenance.
…cycle management

- Include file name as `title` and resolve `mimeType` from file extension in `CameraViewModel` metadata.
- Ensure `jobSucceeded` is called in `WebDavConduit` only after both media and metadata upload attempts complete.
- Update `Conduit` to cancel the coroutine scope when jobs succeed, fail, or are cancelled to prevent leaks.
- Fix file length detection in `Conduit.sanitize()` to support `content://` URIs via `ContentResolver`.
- Remove redundant database updates for `UPLOADING` status in `UploadService`.
- **Process Management**: Implement `isMainProcess` check in `SaveApp` to prevent initialization of WorkManager, Koin, and TOR in the ACRA secondary process.
- **Upload Reliability**:
    - Add retry logic for transient network errors in `IaConduit`.
    - Increase IA upload read timeout to 5 minutes to accommodate large files/TOR overhead.
    - Implement automatic pausing and re-queuing of uploads when TOR connection drops.
- **Upload Gate & Scheduling**:
    - Enhance `UploadGate` with "Wait for Wi-Fi" and "Wait for Tor" options using `JobScheduler` and status watchers for auto-resume.
    - Update `UploadJobScheduler` to respect the `uploadWifiOnly` preference in system job constraints.
- **Database Migration**:
    - Add robust error handling to `MigrationWorker` stages to prevent migration blocks on partial failures.
    - Ensure the legacy Sugar ORM database is deleted upon successful Room migration.
    - Map `Uploading` status to `QUEUED` during migration to ensure clean resume of interrupted tasks.
- **Networking**: Fix a resource leak in `SaveClient` by ensuring WebDAV response bodies are buffered and closed.
- **UX/Strings**: Update connectivity dialogs and strings to clarify TOR and Wi-Fi wait/override behaviors.
- **Version**: Bump `versionCode` to 30033 and `versionName` to 4.0.12.
…WebDAV.

- **Internet Archive**: Added `x-archive-queue-derive: 0` header to defer post-processing until all files are uploaded, reducing server-side resource competition.
- **WebDAV**:
    - Optimized chunked uploads by performing a single initial check to detect resume status, skipping redundant existence checks for subsequent chunks.
    - Increased `CHUNK_SIZE` to 10MB and `CHUNK_FILESIZE_THRESHOLD` to 20MB to reduce HTTP round-trip overhead.
    - Fixed a bug where 1 byte was skipped at each chunk boundary.
    - Configured `OkHttpClient` to force `Connection: close` and disable HTTP/2 to prevent connection reuse corruption and multiplexing conflicts with Nextcloud.
    - Moved credentials to a preemptive interceptor to prevent Sardine from overwriting custom timeouts.
- **General**: Increased network `SEGMENT_SIZE` to 64KB for more efficient I/O.
Remove the `sardine-android` dependency and implement WebDAV functionality (PROPFIND, MKCOL, MOVE, PUT, DELETE) directly using OkHttp and a custom XML parser.

-   **WebDavRepository**: Replaced Sardine's `list` with a manual `PROPFIND` request and `XmlPullParser` to fetch folder contents.
-   **WebDavConduit**:
    -   Migrated single and chunked upload logic to use OkHttp `Request` objects.
    -   Implemented manual WebDAV operations: `headExists`, `headContentLength`, `mkcol`, `move`, and `webdavDelete`.
    -   Improved chunked upload efficiency by using `HEAD` requests instead of `PROPFIND` to check for existing chunks.
    -   Added support for cancelling active network calls.
-   **Conduit**: Wrapped `jobFailed` logic in `NonCancellable` to ensure database updates and event broadcasts complete during service shutdown.
-   **SaveClient**: Removed the `getSardine` helper as it is no longer required.
-   **Dependencies**: Removed `guardianproject-sardine` from Gradle configuration and updated app version to 4.0.15.
- Upgrade AGP to 9.1.1, Compose to 1.11.0, Kotlin to 2.3.21, and Koin to 4.2.1.
- Update various library versions including Datastore, Firebase Crashlytics, Gson, Material3, Media3, Mixpanel, OkHttp, and Tor-Android.
- Remove unused or redundant dependencies and plugins, such as BouncyCastle, Bitcoinj, Guava, Netcipher, and ConstraintLayout.
- Clean up unused library definitions for Picasso, Jsoup, and several Google Play/MLKit components.
- Defer Sugar ORM database deletion to next app startup in `SaveApp` to prevent `SQLITE_READONLY_DBMOVED` errors during active sessions.
- Fix potential deadlock in `HomeScreen` by launching import failure snackbars in a separate scope, ensuring the manual import state is reset first.
- Update `CameraViewModel` to remove confirmed items from the internal capture state so they are not deleted during cleanup.
- Enhance `UploadService` to explicitly handle and report "No vault configured" errors when a conduit cannot be established.
- Improve `Conduit` resolution by falling back to the project's vault ID if the evidence record contains an invalid ID (0), common in legacy Sugar ORM records.
- Clean up unused/commented dependencies in `build.gradle.kts`.
Move the deletion of the legacy Sugar ORM database to before `super.onCreate()` to prevent `SugarApp` from holding an open file descriptor on a deleted file. This prevents `SQLITE_READONLY_DBMOVED (1032)` errors that occurred when attempting to write to the database after it was deleted mid-session.

- Read `is_room_migrated` preference directly from `SharedPreferences` before `SugarApp` initialization.
- Delete `openarchive.db` immediately if migration is already complete.
- Log the deletion status after logger initialization.
…rom SugarORM to Room.

Key changes:
- **Database Migration**: Added logic in `SaveApp.onCreate` to perform a synchronous migration from SugarORM to Room on the first launch (L1) if a legacy database is detected.
- **Deferred Deletion**: Introduced a `sugar_db_delete_pending` flag to defer the deletion of the legacy `openarchive.db` until the subsequent launch (L2), preventing `SQLITE_READONLY_DBMOVED` errors caused by active file descriptors.
- **Worker Updates**: Updated `MigrationWorker` to handle delta migrations and set the pending deletion flag upon completion.
- **Media UI**: Refactored `MediaThumbnail` and `PdfThumbnailView` to use `SubcomposeAsyncImage` painter states for better error handling, replacing basic error drawables with a consistent `MediaPlaceholderIcon` and updating title visibility accordingly.
- **Preferences**: Added `isSugarDbDeletePending` to `Prefs` to track the state of the multi-stage migration and deletion process.
Introduce a standalone `SugarToRoomMigrator` object to facilitate the synchronous migration of records from Sugar ORM to Room.

Key changes:
- Implement `migrate()` to sequence the migration of Spaces, Projects, Collections, and Media.
- Add `migrateSpaces()` to map `SugarSpace` to `VaultEntity` and handle credential storage.
- Add `migrateProjects()` to map `SugarProject` to `ArchiveEntity`.
- Add `migrateCollections()` to map `SugarCollection` to `SubmissionEntity`.
- Add `migrateMedia()` to map `SugarMedia` to `EvidenceEntity`, including status mapping.
- Update `MigrationStateEntity` throughout the process to track migration stages.
Introduce a standalone `SugarToRoomMigrator` object to facilitate the synchronous migration of records from Sugar ORM to Room.

Key changes:
- Implement `migrate()` to sequence the migration of Spaces, Projects, Collections, and Media.
- Add `migrateSpaces()` to map `SugarSpace` to `VaultEntity` and handle credential storage.
- Add `migrateProjects()` to map `SugarProject` to `ArchiveEntity`.
- Add `migrateCollections()` to map `SugarCollection` to `SubmissionEntity`.
- Add `migrateMedia()` to map `SugarMedia` to `EvidenceEntity`, including status mapping.
- Update `MigrationStateEntity` throughout the process to track migration stages.
…tore

Ensures the DataStore is a process-wide singleton for the credential file, preventing conflicts between migration-time and Koin-injected instances.

- Implement a thread-safe `getOrCreateDataStore` pattern in the companion object.
- Update the `dataStore` property to use the shared singleton instance.
- Adjust visibility of internal security constants.
…tore

Ensures the DataStore is a process-wide singleton for the credential file, preventing conflicts between migration-time and Koin-injected instances.

- Implement a thread-safe `getOrCreateDataStore` pattern in the companion object.
- Update the `dataStore` property to use the shared singleton instance.
- Adjust visibility of internal security constants.
Update versionCode to 30036 and versionName to 4.0.16 in app/build.gradle.kts.
- Implement pre-flight capacity checks using the Internet Archive `check_limit` API to avoid 503 Slow Down errors.
- Add `isAlreadyUploaded` check to skip re-uploading files already present on IA after partial successes.
- Improve retry logic with reduced base delays, exponential backoff, and jitter to avoid lockstep retries.
- Handle HTTP 307/301/302 redirects manually for PUT requests with streaming bodies.
- Introduce `IaSlowDownException` to treat IA server overloads as transient, re-queuing items for later retry instead of failing.
- Promote `UploadService` to a foreground service on pre-API 34 devices to prevent process termination during uploads.
- Add `FOREGROUND_SERVICE` permission to `AndroidManifest.xml`.
- Update version to 4.0.17 (30037).
…ound services.

- **Passcode Management**: Move `PasscodeGate` registration from `HomeActivity` to `SaveApp` (Process lifecycle) to prevent auth resets during activity recreation (e.g., theme toggles).
- **HomeActivity**: Add state tracking to prevent redundant permission checks and media imports during config changes. Delay upload checks and URI flushing until the app is confirmed unlocked.
- **Tor & Snowbird Services**: Ensure `startForeground` is only called once per service lifecycle. Update `TorForegroundService` to use `NotificationManager.notify()` for status updates to avoid notification flashing.
- **UI Improvements**: Fix `DropdownMenu` background color in `FolderBar` to correctly support dark mode.
- **Cleanup**: Remove unnecessary foreground service behavior flags for Android 12+ and update notification text for clarity.
@upulw2020 upulw2020 changed the title WIP: Next Prof Release Candidate WIP: Next Prod Release Candidate May 5, 2026
Prathieshna Vekneswaran added 8 commits May 6, 2026 13:57
- **Session Recovery**: Implement `resetStaleUploading` to move items stuck in `UPLOADING` back to the `QUEUED` state on app startup, preventing permanent UI spinners after crashes or force-kills.
- **Improved Timeouts**: Increase `writeTimeout` and `readTimeout` to 5 minutes for Internet Archive and WebDAV uploads to accommodate slow connections (e.g., Tor) and server-side processing.
- **Transient Error Handling**: Automatically re-queue uploads on `SocketTimeoutException` instead of marking them as failed.
- **Optimized IA Uploads**: Remove the pre-flight `check_limit` API call in favor of existing 503 exponential backoff logic and skip metadata checks for first-attempt uploads.
- **Process Lifecycle**: Ensure queued uploads are re-scheduled when the app returns to the foreground and is unlocked.
- **Bug Fix**: Reset the internal `mRunning` flag in `UploadService` to prevent silent drops of upload sessions if the service is restarted rapidly.
- **Cleanup**: Remove the unused `GET_ACCOUNTS` permission from the manifest.
- **Navigation & State Management**:
  - Implemented persistence for the last selected project ID in `Prefs`.
  - Fixed a race condition in `HomeViewModel` to prevent resetting selected projects during initial data loads.
  - Improved `HomeActivity` to queue and flush pending shared URIs after passcode authentication.
  - Optimized `HomeScreen` pager sync to skip initial emissions, preventing conflicts with persisted scroll positions.

- **C2PA & Provenance**:
  - Added extensive debug logging for C2PA manifest generation and verification.
  - Resolved a race condition where camera results were intercepted by the wrong screen, causing missing vault context for C2PA.
  - Introduced a preview-specific navigation result key to isolate camera captures launched from the media preview screen.
  - Ensured `MediaPicker` correctly passes `vaultType` to maintain provenance data during imports.

- **UI & UX**:
  - Refined theme support for the folder/server picker, ensuring correct `surface` and `onSurface` colors in both light and dark modes.
  - Replaced the full-screen loading overlay in login screens with inline `enabled` states for text fields to improve responsiveness.
  - Updated the "New Folder" validation to allow spaces while strictly forbidding `\`, `/`, and `*`.
  - Clarified error messaging for invalid folder characters.

- **Maintenance**:
  - Bumped `versionCode` to 30038 and `versionName` to 4.0.18.
  - Updated `targetSdk` to 36.
- Wrap authentication calls in try-catch blocks to capture network and connection exceptions.
- Replace generic `isLoginError` boolean with `LoginErrorType` enum to support specific error messaging for network timeouts, unavailable network, Tor connection status, and invalid credentials.
- Update `InternetArchiveLoginViewModel` to map caught exceptions to the appropriate `LoginErrorType`.
- Update `InternetArchiveLoginScreen` to display localized error messages based on the error type.
- Add new string resources for Tor connection, network timeout, and general network errors.
…ve uploads and improve server error handling.

Specific changes:
- Added `CredentialsExpiredException` to handle 401 Unauthorized responses from Internet Archive S3.
- Implemented encrypted storage for login passwords in `VaultCredentialStore` and `TinkVaultCredentialStore` using AES-256-GCM and Android Keystore.
- Updated `InternetArchiveAuthenticator` to support silent re-authentication by refreshing S3 keys using stored credentials.
- Refactored `IaConduit` to upload metadata before content to reduce 503 "Slow Down" errors and added automatic retry logic for expired credentials.
- Improved exponential backoff and `Retry-After` header handling for 502/503/504 server errors.
- Enhanced `RequestBodyUtil` with a larger segment size (256 KB) for more efficient uploads.
- Updated `InternetArchiveLoginViewModel` to store login passwords securely upon successful login and clear plaintext credentials from UI state.
- Added a specific `SERVER_ERROR` state for the login UI to handle 5xx responses.
- Removed `android:usesCleartextTraffic="true"` from the manifest.
- Version bump to 4.0.19 (code 30039).
…ve uploads and improve server error handling.

Specific changes:
- Added `CredentialsExpiredException` to handle 401 Unauthorized responses from Internet Archive S3.
- Implemented encrypted storage for login passwords in `VaultCredentialStore` and `TinkVaultCredentialStore` using AES-256-GCM and Android Keystore.
- Updated `InternetArchiveAuthenticator` to support silent re-authentication by refreshing S3 keys using stored credentials.
- Refactored `IaConduit` to upload metadata before content to reduce 503 "Slow Down" errors and added automatic retry logic for expired credentials.
- Improved exponential backoff and `Retry-After` header handling for 502/503/504 server errors.
- Enhanced `RequestBodyUtil` with a larger segment size (256 KB) for more efficient uploads.
- Updated `InternetArchiveLoginViewModel` to store login passwords securely upon successful login and clear plaintext credentials from UI state.
- Added a specific `SERVER_ERROR` state for the login UI to handle 5xx responses.
- Removed `android:usesCleartextTraffic="true"` from the manifest.
- Version bump to 4.0.19 (code 30039).
Internet Archive:
- Swap upload order: content is now uploaded before metadata to prevent orphaned item stubs.
- Add security validation for redirects to ensure they remain within archive.org domains.
- Update header sanitization to preserve Unicode/non-ASCII characters while stripping control characters.
- Remove unused `uploadProofFiles` method.

WebDAV:
- Implement a retry mechanism with exponential backoff and jitter for 5xx errors and network failures.
- Optimize chunked uploads by using a reusable buffer and `readNBytes` to avoid unnecessary allocations and short-read issues.

Networking/Tor:
- Refine Tor circuit isolation by scoping the `Authenticator` to the specific SOCKS5 proxy host and port, preventing accidental credential leakage to other challenges.
Internet Archive:
- Swap upload order: content is now uploaded before metadata to prevent orphaned item stubs.
- Add security validation for redirects to ensure they remain within archive.org domains.
- Update header sanitization to preserve Unicode/non-ASCII characters while stripping control characters.
- Remove unused `uploadProofFiles` method.

WebDAV:
- Implement a retry mechanism with exponential backoff and jitter for 5xx errors and network failures.
- Optimize chunked uploads by using a reusable buffer and `readNBytes` to avoid unnecessary allocations and short-read issues.

Networking/Tor:
- Refine Tor circuit isolation by scoping the `Authenticator` to the specific SOCKS5 proxy host and port, preventing accidental credential leakage to other challenges.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs QA Should be done now, please test!

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants