mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-27 15:17:38 +00:00
feat: Update bundle identifiers and add logging configuration profile
- Updated macOS test bundle IDs to use consistent naming pattern: - sh.vibetunnel.vibetunnelTests → sh.vibetunnel.vibetunnel.tests - sh.vibetunnel.vibetunnelTests.debug → sh.vibetunnel.vibetunnel.tests.debug - Updated iOS test bundle ID: - sh.vibetunnel.VibeTunnelTests-Mobile → sh.vibetunnel.ios.tests - Fixed iOS logging to use sh.vibetunnel.ios subsystem consistently - Created logging configuration profile in apple/logging/ to enable full debug logging - Configuration profile covers all VibeTunnel subsystems and bundle IDs - Updated documentation to reflect new bundle identifiers and logging setup
This commit is contained in:
parent
97d51fbe8d
commit
eab1e6c962
14 changed files with 393 additions and 27 deletions
54
README.md
54
README.md
|
|
@ -948,6 +948,60 @@ sudo tccutil reset ScreenCapture sh.vibetunnel.vibetunnel.debug # For debug bui
|
||||||
sudo tccutil reset AppleEvents
|
sudo tccutil reset AppleEvents
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Logging and Privacy
|
||||||
|
|
||||||
|
VibeTunnel uses Apple's unified logging system with the subsystem `sh.vibetunnel.vibetunnel`. By default, macOS redacts sensitive runtime data in logs, showing `<private>` instead of actual values. This is a privacy feature to prevent accidental exposure of sensitive information.
|
||||||
|
|
||||||
|
### Bundle Identifiers
|
||||||
|
|
||||||
|
VibeTunnel uses the following bundle identifiers:
|
||||||
|
|
||||||
|
**Production:**
|
||||||
|
- `sh.vibetunnel.vibetunnel` - Main macOS app and logging subsystem
|
||||||
|
- `sh.vibetunnel.vibetunnel.debug` - Debug builds of the macOS app
|
||||||
|
|
||||||
|
**Testing:**
|
||||||
|
- `sh.vibetunnel.vibetunnel.tests` - macOS test suite
|
||||||
|
- `sh.vibetunnel.ios.tests` - iOS test suite
|
||||||
|
|
||||||
|
**iOS:**
|
||||||
|
- `sh.vibetunnel.ios` - iOS keychain service and URL scheme
|
||||||
|
|
||||||
|
### Viewing Unredacted Logs
|
||||||
|
|
||||||
|
To see full log details for debugging, you have several options:
|
||||||
|
|
||||||
|
1. **Use the vtlog script with sudo** (reveals private data):
|
||||||
|
```bash
|
||||||
|
sudo ./scripts/vtlog.sh --info
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Configure passwordless sudo** for the log command:
|
||||||
|
```bash
|
||||||
|
# Add to sudoers (replace 'yourusername' with your actual username)
|
||||||
|
sudo visudo
|
||||||
|
# Add this line:
|
||||||
|
yourusername ALL=(ALL) NOPASSWD: /usr/bin/log
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Enable private data logging** using a plist file (recommended):
|
||||||
|
```bash
|
||||||
|
# Create the plist to enable private data for VibeTunnel
|
||||||
|
sudo mkdir -p /Library/Preferences/Logging/Subsystems
|
||||||
|
sudo tee /Library/Preferences/Logging/Subsystems/sh.vibetunnel.vibetunnel.plist > /dev/null << 'EOF'
|
||||||
|
<?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>Enable-Private-Data</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
For more detailed information about logging privacy and additional methods, see [apple/docs/logging-private-fix.md](apple/docs/logging-private-fix.md).
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
We welcome contributions! VibeTunnel is a community-driven project and we'd love to have you join us.
|
We welcome contributions! VibeTunnel is a community-driven project and we'd love to have you join us.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,35 @@
|
||||||
# Fixing macOS Log Redaction for VibeTunnel
|
# Fixing macOS Log Redaction for VibeTunnel
|
||||||
|
|
||||||
|
## Quick Fix: Configuration Profile (Recommended)
|
||||||
|
|
||||||
|
We provide a ready-to-use configuration profile that enables full debug logging for VibeTunnel:
|
||||||
|
|
||||||
|
**Location**: `apple/logging/VibeTunnel-Logging.mobileconfig`
|
||||||
|
|
||||||
|
### Installing the Profile
|
||||||
|
|
||||||
|
#### macOS
|
||||||
|
1. Double-click `apple/logging/VibeTunnel-Logging.mobileconfig`
|
||||||
|
2. System Settings will open to the Profiles section
|
||||||
|
3. Click "Install..." and enter your password
|
||||||
|
4. Restart VibeTunnel
|
||||||
|
|
||||||
|
#### iOS
|
||||||
|
1. AirDrop or email the profile to your device
|
||||||
|
2. Open Settings → General → VPN & Device Management
|
||||||
|
3. Install the "VibeTunnel Debug Logging" profile
|
||||||
|
4. Restart the VibeTunnel app
|
||||||
|
|
||||||
|
### Verifying It Works
|
||||||
|
```bash
|
||||||
|
# You should now see full details instead of <private>
|
||||||
|
./scripts/vtlog.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Removing the Profile
|
||||||
|
- **macOS**: System Settings → Privacy & Security → Profiles → Remove
|
||||||
|
- **iOS**: Settings → General → VPN & Device Management → Remove Profile
|
||||||
|
|
||||||
## The Problem
|
## The Problem
|
||||||
|
|
||||||
When viewing VibeTunnel logs using Apple's unified logging system, you'll see `<private>` instead of actual values:
|
When viewing VibeTunnel logs using Apple's unified logging system, you'll see `<private>` instead of actual values:
|
||||||
|
|
@ -133,18 +163,83 @@ logger.info("Connected to \(sessionId)")
|
||||||
logger.info("Connected to \(sessionId, privacy: .public)")
|
logger.info("Connected to \(sessionId, privacy: .public)")
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Configure logging system
|
### 4. Configure logging system (Modern Methods)
|
||||||
|
|
||||||
|
#### Method A: Plist File (Recommended)
|
||||||
|
|
||||||
|
Create a plist file to enable private data logging for VibeTunnel:
|
||||||
|
|
||||||
Temporarily enable private data for all VibeTunnel logs:
|
|
||||||
```bash
|
```bash
|
||||||
sudo log config --mode "private_data:on" --subsystem sh.vibetunnel.vibetunnel
|
# Create the directory if it doesn't exist
|
||||||
|
sudo mkdir -p /Library/Preferences/Logging/Subsystems
|
||||||
|
|
||||||
|
# Create the plist file
|
||||||
|
sudo tee /Library/Preferences/Logging/Subsystems/sh.vibetunnel.vibetunnel.plist > /dev/null << 'EOF'
|
||||||
|
<?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>Enable-Private-Data</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Verify it was created
|
||||||
|
ls -la /Library/Preferences/Logging/Subsystems/sh.vibetunnel.vibetunnel.plist
|
||||||
```
|
```
|
||||||
|
|
||||||
To revert:
|
To remove:
|
||||||
```bash
|
```bash
|
||||||
sudo log config --mode "private_data:off" --subsystem sh.vibetunnel.vibetunnel
|
sudo rm /Library/Preferences/Logging/Subsystems/sh.vibetunnel.vibetunnel.plist
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Method B: Configuration Profile
|
||||||
|
|
||||||
|
For managed environments or multiple subsystems, create a configuration profile:
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<?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>PayloadContent</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>com.apple.system.logging</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>com.example.logging.vibetunnel</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>$(uuidgen)</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>Subsystems</key>
|
||||||
|
<dict>
|
||||||
|
<key>sh.vibetunnel.vibetunnel</key>
|
||||||
|
<dict>
|
||||||
|
<key>Enable-Private-Data</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>com.example.vibetunnel.logging</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>$(uuidgen)</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>Configuration</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
```
|
||||||
|
|
||||||
|
Install via System Settings → Profiles.
|
||||||
|
|
||||||
|
**Note:** The old `private_data:on` flag was removed in macOS Catalina and no longer works.
|
||||||
|
|
||||||
## Using vtlog.sh
|
## Using vtlog.sh
|
||||||
|
|
||||||
With passwordless sudo configured, you can now use:
|
With passwordless sudo configured, you can now use:
|
||||||
|
|
|
||||||
79
apple/logging/README.md
Normal file
79
apple/logging/README.md
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
# VibeTunnel Logging Configuration Profile
|
||||||
|
|
||||||
|
This directory contains the configuration profile for enabling full debug logging in VibeTunnel apps.
|
||||||
|
|
||||||
|
## What It Does
|
||||||
|
|
||||||
|
The `VibeTunnel-Logging.mobileconfig` profile enables:
|
||||||
|
- Debug-level logging for both macOS and iOS apps
|
||||||
|
- Visibility of private data (no more `<private>` tags)
|
||||||
|
- Persistent logging at debug level
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
1. Double-click `VibeTunnel-Logging.mobileconfig`
|
||||||
|
2. System Settings will open
|
||||||
|
3. Go to Privacy & Security → Profiles
|
||||||
|
4. Click on "VibeTunnel Debug Logging"
|
||||||
|
5. Click "Install..."
|
||||||
|
6. Enter your password when prompted
|
||||||
|
7. Restart VibeTunnel for changes to take effect
|
||||||
|
|
||||||
|
### iOS
|
||||||
|
1. AirDrop or email the `VibeTunnel-Logging.mobileconfig` to your iOS device
|
||||||
|
2. Tap the file to open it
|
||||||
|
3. iOS will prompt to review the profile
|
||||||
|
4. Go to Settings → General → VPN & Device Management
|
||||||
|
5. Tap on "VibeTunnel Debug Logging"
|
||||||
|
6. Tap "Install" and enter your passcode
|
||||||
|
7. Restart the VibeTunnel app
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
After installation, logs should show full details:
|
||||||
|
```bash
|
||||||
|
# macOS - using vtlog script
|
||||||
|
./scripts/vtlog.sh
|
||||||
|
|
||||||
|
# iOS - in Xcode console or Console.app
|
||||||
|
# You should see actual values instead of <private>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Removal
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
1. System Settings → Privacy & Security → Profiles
|
||||||
|
2. Select "VibeTunnel Debug Logging"
|
||||||
|
3. Click the minus (-) button
|
||||||
|
4. Confirm removal
|
||||||
|
|
||||||
|
### iOS
|
||||||
|
1. Settings → General → VPN & Device Management
|
||||||
|
2. Tap "VibeTunnel Debug Logging"
|
||||||
|
3. Tap "Remove Profile"
|
||||||
|
4. Enter passcode to confirm
|
||||||
|
|
||||||
|
## Security Note
|
||||||
|
|
||||||
|
This profile enables detailed logging which may include sensitive information. Only install on development devices and remove when no longer needed for debugging.
|
||||||
|
|
||||||
|
## Technical Details
|
||||||
|
|
||||||
|
The profile configures logging for all VibeTunnel subsystems:
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
- `sh.vibetunnel.vibetunnel` - Main macOS app and all components
|
||||||
|
- `sh.vibetunnel.vibetunnel.debug` - Debug builds
|
||||||
|
- `sh.vibetunnel.vibetunnel.tests` - Test suite
|
||||||
|
- `sh.vibetunnel.vibetunnel.tests.debug` - Debug test builds
|
||||||
|
|
||||||
|
### iOS
|
||||||
|
- `sh.vibetunnel.vibetunnel-mobile` - Main iOS app bundle ID
|
||||||
|
- `sh.vibetunnel.ios` - Alternative iOS bundle ID (used in services)
|
||||||
|
- `sh.vibetunnel.ios.tests` - iOS test suite
|
||||||
|
|
||||||
|
All subsystems are configured to:
|
||||||
|
- Enable at Debug level
|
||||||
|
- Persist at Debug level
|
||||||
|
- Show private data (no `<private>` redaction)
|
||||||
138
apple/logging/VibeTunnel-Logging.mobileconfig
Normal file
138
apple/logging/VibeTunnel-Logging.mobileconfig
Normal file
|
|
@ -0,0 +1,138 @@
|
||||||
|
<?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>PayloadContent</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>com.apple.system.logging</string>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>sh.vibetunnel.logging.all</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>A7B8C9D0-1234-5678-9ABC-DEF012345678</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>VibeTunnel Logging Configuration</string>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>Enables private data in logs for all VibeTunnel apps and components</string>
|
||||||
|
<key>Subsystems</key>
|
||||||
|
<dict>
|
||||||
|
<!-- Main macOS app and all its components -->
|
||||||
|
<key>sh.vibetunnel.vibetunnel</key>
|
||||||
|
<dict>
|
||||||
|
<key>DEFAULT-OPTIONS</key>
|
||||||
|
<dict>
|
||||||
|
<key>Level</key>
|
||||||
|
<dict>
|
||||||
|
<key>Enable</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<!-- macOS debug build -->
|
||||||
|
<key>sh.vibetunnel.vibetunnel.debug</key>
|
||||||
|
<dict>
|
||||||
|
<key>DEFAULT-OPTIONS</key>
|
||||||
|
<dict>
|
||||||
|
<key>Level</key>
|
||||||
|
<dict>
|
||||||
|
<key>Enable</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<!-- macOS tests -->
|
||||||
|
<key>sh.vibetunnel.vibetunnel.tests</key>
|
||||||
|
<dict>
|
||||||
|
<key>DEFAULT-OPTIONS</key>
|
||||||
|
<dict>
|
||||||
|
<key>Level</key>
|
||||||
|
<dict>
|
||||||
|
<key>Enable</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<!-- macOS tests debug -->
|
||||||
|
<key>sh.vibetunnel.vibetunnel.tests.debug</key>
|
||||||
|
<dict>
|
||||||
|
<key>DEFAULT-OPTIONS</key>
|
||||||
|
<dict>
|
||||||
|
<key>Level</key>
|
||||||
|
<dict>
|
||||||
|
<key>Enable</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<!-- iOS app (main bundle ID) -->
|
||||||
|
<key>sh.vibetunnel.vibetunnel-mobile</key>
|
||||||
|
<dict>
|
||||||
|
<key>DEFAULT-OPTIONS</key>
|
||||||
|
<dict>
|
||||||
|
<key>Level</key>
|
||||||
|
<dict>
|
||||||
|
<key>Enable</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<!-- iOS app (alternative bundle ID) -->
|
||||||
|
<key>sh.vibetunnel.ios</key>
|
||||||
|
<dict>
|
||||||
|
<key>DEFAULT-OPTIONS</key>
|
||||||
|
<dict>
|
||||||
|
<key>Level</key>
|
||||||
|
<dict>
|
||||||
|
<key>Enable</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<!-- iOS tests -->
|
||||||
|
<key>sh.vibetunnel.ios.tests</key>
|
||||||
|
<dict>
|
||||||
|
<key>DEFAULT-OPTIONS</key>
|
||||||
|
<dict>
|
||||||
|
<key>Level</key>
|
||||||
|
<dict>
|
||||||
|
<key>Enable</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
<key>Persist</key>
|
||||||
|
<string>Debug</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>PayloadIdentifier</key>
|
||||||
|
<string>sh.vibetunnel.logging</string>
|
||||||
|
<key>PayloadUUID</key>
|
||||||
|
<string>C9D0E1F2-3456-7890-1CDE-F23456789012</string>
|
||||||
|
<key>PayloadType</key>
|
||||||
|
<string>Configuration</string>
|
||||||
|
<key>PayloadVersion</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>PayloadDisplayName</key>
|
||||||
|
<string>VibeTunnel Debug Logging</string>
|
||||||
|
<key>PayloadDescription</key>
|
||||||
|
<string>Enables full debug logging with private data visibility for VibeTunnel applications. Install this profile to see complete log details instead of <private> tags.</string>
|
||||||
|
<key>PayloadOrganization</key>
|
||||||
|
<string>VibeTunnel</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
|
@ -164,7 +164,7 @@ vtlog | grep ServerConfig
|
||||||
vtlog -v
|
vtlog -v
|
||||||
|
|
||||||
# Monitor specific subsystem
|
# Monitor specific subsystem
|
||||||
vtlog --subsystem sh.vibetunnel.vibetunnel
|
vtlog --subsystem sh.vibetunnel.ios
|
||||||
```
|
```
|
||||||
|
|
||||||
### Code Quality
|
### Code Quality
|
||||||
|
|
|
||||||
|
|
@ -333,7 +333,7 @@
|
||||||
ENABLE_TESTING_FRAMEWORKS = YES;
|
ENABLE_TESTING_FRAMEWORKS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "sh.vibetunnel.VibeTunnelTests-Mobile";
|
PRODUCT_BUNDLE_IDENTIFIER = "sh.vibetunnel.ios.tests";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SWIFT_VERSION = 6.0;
|
SWIFT_VERSION = 6.0;
|
||||||
|
|
@ -426,7 +426,7 @@
|
||||||
ENABLE_TESTING_FRAMEWORKS = YES;
|
ENABLE_TESTING_FRAMEWORKS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = "sh.vibetunnel.VibeTunnelTests-Mobile";
|
PRODUCT_BUNDLE_IDENTIFIER = "sh.vibetunnel.ios.tests";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SDKROOT = iphoneos;
|
SDKROOT = iphoneos;
|
||||||
SWIFT_VERSION = 6.0;
|
SWIFT_VERSION = 6.0;
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@
|
||||||
<string>vibetunnel</string>
|
<string>vibetunnel</string>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleURLName</key>
|
<key>CFBundleURLName</key>
|
||||||
<string>com.vibetunnel.app</string>
|
<string>sh.vibetunnel.ios</string>
|
||||||
</dict>
|
</dict>
|
||||||
</array>
|
</array>
|
||||||
<key>CFBundleDocumentTypes</key>
|
<key>CFBundleDocumentTypes</key>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import Security
|
||||||
/// Service for securely storing credentials in the iOS Keychain.
|
/// Service for securely storing credentials in the iOS Keychain.
|
||||||
/// Provides secure storage and retrieval of passwords and tokens.
|
/// Provides secure storage and retrieval of passwords and tokens.
|
||||||
class KeychainService: KeychainServiceProtocol {
|
class KeychainService: KeychainServiceProtocol {
|
||||||
private let serviceName = "com.vibetunnel.ios"
|
private let serviceName = "sh.vibetunnel.ios"
|
||||||
|
|
||||||
/// Errors that can occur during keychain operations.
|
/// Errors that can occur during keychain operations.
|
||||||
/// Provides specific error cases for keychain failures.
|
/// Provides specific error cases for keychain failures.
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,8 @@ struct Logger {
|
||||||
|
|
||||||
init(category: String) {
|
init(category: String) {
|
||||||
self.category = category
|
self.category = category
|
||||||
// Use the same subsystem as the Mac app for consistency
|
// Use iOS-specific subsystem for proper log filtering
|
||||||
self.osLogger = os.Logger(subsystem: "sh.vibetunnel.vibetunnel", category: category)
|
self.osLogger = os.Logger(subsystem: "sh.vibetunnel.ios", category: category)
|
||||||
}
|
}
|
||||||
|
|
||||||
func verbose(_ message: String) {
|
func verbose(_ message: String) {
|
||||||
|
|
|
||||||
|
|
@ -300,14 +300,14 @@ struct AuthenticationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
let item = KeychainItem(
|
let item = KeychainItem(
|
||||||
service: "com.vibetunnel.app",
|
service: "sh.vibetunnel.ios",
|
||||||
account: "user-token",
|
account: "user-token",
|
||||||
data: "secret-token".data(using: .utf8)!,
|
data: "secret-token".data(using: .utf8)!,
|
||||||
accessGroup: nil
|
accessGroup: nil
|
||||||
)
|
)
|
||||||
|
|
||||||
#expect(item.query[kSecClass as String] as? String == kSecClassGenericPassword as String)
|
#expect(item.query[kSecClass as String] as? String == kSecClassGenericPassword as String)
|
||||||
#expect(item.query[kSecAttrService as String] as? String == "com.vibetunnel.app")
|
#expect(item.query[kSecAttrService as String] as? String == "sh.vibetunnel.ios")
|
||||||
#expect(item.query[kSecAttrAccount as String] as? String == "user-token")
|
#expect(item.query[kSecAttrAccount as String] as? String == "user-token")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,7 @@ struct FileSystemTests {
|
||||||
@Test("Sandbox path validation")
|
@Test("Sandbox path validation")
|
||||||
func sandboxPaths() {
|
func sandboxPaths() {
|
||||||
struct SandboxValidator {
|
struct SandboxValidator {
|
||||||
let appGroupIdentifier = "group.com.vibetunnel"
|
let appGroupIdentifier = "group.sh.vibetunnel"
|
||||||
|
|
||||||
var documentsDirectory: String {
|
var documentsDirectory: String {
|
||||||
"~/Documents"
|
"~/Documents"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
SUBSYSTEM="sh.vibetunnel.vibetunnel"
|
SUBSYSTEM="sh.vibetunnel.ios"
|
||||||
DEFAULT_LEVEL="info"
|
DEFAULT_LEVEL="info"
|
||||||
|
|
||||||
# Colors for output
|
# Colors for output
|
||||||
|
|
|
||||||
|
|
@ -512,7 +512,7 @@
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = "$(inherited)";
|
MARKETING_VERSION = "$(inherited)";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = sh.vibetunnel.vibetunnelTests.debug;
|
PRODUCT_BUNDLE_IDENTIFIER = sh.vibetunnel.vibetunnel.tests.debug;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VibeTunnel.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/VibeTunnel";
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VibeTunnel.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/VibeTunnel";
|
||||||
|
|
@ -529,7 +529,7 @@
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
MACOSX_DEPLOYMENT_TARGET = 14.0;
|
||||||
MARKETING_VERSION = "$(inherited)";
|
MARKETING_VERSION = "$(inherited)";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = sh.vibetunnel.vibetunnelTests;
|
PRODUCT_BUNDLE_IDENTIFIER = sh.vibetunnel.vibetunnel.tests;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_EMIT_LOC_STRINGS = NO;
|
SWIFT_EMIT_LOC_STRINGS = NO;
|
||||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VibeTunnel.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/VibeTunnel";
|
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/VibeTunnel.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/VibeTunnel";
|
||||||
|
|
|
||||||
|
|
@ -2107,8 +2107,8 @@ body.initial-session-load .session-flex-responsive > session-card:nth-child(n +
|
||||||
/* Custom styling */
|
/* Custom styling */
|
||||||
width: 1rem;
|
width: 1rem;
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
background-color: rgb(var(--color-bg-primary));
|
background-color: var(--color-bg);
|
||||||
border: 2px solid rgb(var(--color-border) / 0.5);
|
border: 2px solid color-mix(in srgb, var(--color-border) 50%, transparent);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
@ -2122,14 +2122,14 @@ body.initial-session-load .session-flex-responsive > session-card:nth-child(n +
|
||||||
|
|
||||||
/* Hover state */
|
/* Hover state */
|
||||||
.session-toggle-checkbox:hover:not(:checked) {
|
.session-toggle-checkbox:hover:not(:checked) {
|
||||||
border-color: rgb(var(--color-border));
|
border-color: var(--color-border);
|
||||||
background-color: rgb(var(--color-bg-secondary));
|
background-color: var(--color-bg-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checked state */
|
/* Checked state */
|
||||||
.session-toggle-checkbox:checked {
|
.session-toggle-checkbox:checked {
|
||||||
background-color: rgb(var(--color-primary) / 0.15);
|
background-color: color-mix(in srgb, var(--color-primary) 15%, transparent);
|
||||||
border-color: rgb(var(--color-primary) / 0.5);
|
border-color: color-mix(in srgb, var(--color-primary) 50%, transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checkmark using pseudo-element */
|
/* Checkmark using pseudo-element */
|
||||||
|
|
@ -2139,7 +2139,7 @@ body.initial-session-load .session-flex-responsive > session-card:nth-child(n +
|
||||||
height: 0.5rem;
|
height: 0.5rem;
|
||||||
transform: scale(0);
|
transform: scale(0);
|
||||||
transition: transform 0.15s ease-in-out;
|
transition: transform 0.15s ease-in-out;
|
||||||
background-color: rgb(var(--color-primary));
|
background-color: var(--color-primary);
|
||||||
|
|
||||||
/* Create checkmark shape using clip-path */
|
/* Create checkmark shape using clip-path */
|
||||||
clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
|
clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
|
||||||
|
|
@ -2153,10 +2153,10 @@ body.initial-session-load .session-flex-responsive > session-card:nth-child(n +
|
||||||
/* Focus state */
|
/* Focus state */
|
||||||
.session-toggle-checkbox:focus {
|
.session-toggle-checkbox:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
box-shadow: 0 0 0 2px rgb(var(--color-primary) / 0.25);
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 25%, transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Focus visible for keyboard navigation */
|
/* Focus visible for keyboard navigation */
|
||||||
.session-toggle-checkbox:focus-visible {
|
.session-toggle-checkbox:focus-visible {
|
||||||
box-shadow: 0 0 0 2px rgb(var(--color-primary) / 0.4);
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-primary) 40%, transparent);
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue