Improve documentation clarity and fix technical inaccuracies

Pavel Baksy 2026-01-13 16:59:00 +01:00
parent 72a00e5cd6
commit 26a0610652
9 changed files with 152 additions and 924 deletions

@ -257,11 +257,10 @@ const timeout = roster.getVariable('timeout') || '30';
console.log('Using timeout:', timeout);
```
**Important Notes:**
**Notes:**
- Returns `undefined` if variable doesn't exist
- Gets value from currently selected environment
- Can access both regular and [[Sensitive-Variables|sensitive variables]]
- Sensitive variable values are automatically decrypted from keyring
- Gets value from selected environment
- Sensitive variables are automatically decrypted
#### `roster.setVariable(name, value)`
@ -287,12 +286,12 @@ roster.setVariable('auth_token', token);
roster.setVariable('session_id', generateSessionId());
```
**Important Notes:**
**Notes:**
- Creates variable if it doesn't exist
- Updates value in currently selected environment
- Updates value in selected environment
- Variable name must be alphanumeric + underscore
- If variable is marked as sensitive, value goes to keyring automatically
- Value is converted to string
- Sensitive variables automatically routed to keyring
- Value converted to string
#### `roster.setVariables(object)`
@ -323,11 +322,9 @@ roster.setVariables({
console.log('Saved authentication tokens');
```
**Important Notes:**
- All variables updated in single operation
**Notes:**
- More efficient than multiple `setVariable()` calls
- Same validation rules as `setVariable()`
- Sensitive variables automatically routed to keyring
### Properties
@ -554,65 +551,21 @@ if (response.statusCode === 200) {
## Limitations
### No Asynchronous Operations
- No `setTimeout` / `setInterval`
- No `Promise` / `async` / `await`
- No `fetch()` / `XMLHttpRequest`
- Scripts execute synchronously
### No External Libraries
- Cannot import npm packages
- Cannot `require()` external modules
Scripts run in a sandboxed, synchronous environment:
- No async operations (setTimeout, Promises, async/await)
- No external libraries or npm packages
- No file system or shell access
- No network requests (use Roster's request system)
- Only built-in JavaScript objects available
### No File System Access
- Cannot read/write files
- Cannot execute shell commands
- Cannot access environment variables (use Roster variables instead)
### No Network Access
- Cannot make additional HTTP requests
- Use Roster's request system instead
## Type Reference
### Variable Name Pattern
Variable names must match: `/^\w+$/`
Valid:
- `api_key`
- `user_id`
- `access_token`
- `BASE_URL`
- `token123`
Invalid:
- `api-key` (hyphen not allowed)
- `api.key` (dot not allowed)
- `api key` (space not allowed)
- `@token` (special character)
### Type Conversions
Variables are always stored as strings:
**Variable names** must match `/^\w+$/` (alphanumeric + underscore only).
**Variables are always strings**. Convert numbers and booleans when setting/getting:
```javascript
// Numbers must be converted
roster.setVariable('count', data.count.toString());
// Read as number
const count = parseInt(roster.getVariable('count'), 10);
// Booleans must be converted
roster.setVariable('is_active', data.active.toString());
// Read as boolean
const isActive = roster.getVariable('is_active') === 'true';
```
## Next Steps

32
FAQ.md

@ -33,9 +33,7 @@ Support for Flathub is planned for future releases.
### What dependencies does Roster need?
Runtime: GTK 4, libadwaita 1, Python 3, libsoup3, libsecret, GJS
See [[Installation]] for complete dependency list.
GTK 4, libadwaita 1, Python 3, libsoup3, libsecret, and GJS. See [[Installation]] for details.
## Variables and Environments
@ -76,10 +74,7 @@ Regular variables are stored in plain text. Always mark secrets as sensitive!
### Where are my secrets stored?
Sensitive variables are stored in GNOME Keyring at:
- Native: `~/.local/share/keyrings/`
- Encrypted with your login password
- Same security as browser passwords, WiFi credentials
Sensitive variables are encrypted in GNOME Keyring (`~/.local/share/keyrings/`) using your login password. Same security as browser passwords and WiFi credentials.
### Can I view my keyring secrets?
@ -181,10 +176,9 @@ flatpak info --show-permissions cz.bugsy.roster
### Scripts not executing
**Check:**
1. Request is saved (scripts only work on saved requests)
2. Script has no syntax errors
3. Check script output tabs for errors
4. GJS (gjs package) is installed
1. Script has no syntax errors
2. Check script output panels for errors
3. GJS (gjs package) is installed
### Request failing with SSL errors
@ -235,23 +229,13 @@ Yes! Open an issue with the "enhancement" label.
## Comparison
### How is Roster different from Postman?
### How is Roster different from Postman/Insomnia?
- **Roster**: Native GNOME app, lightweight, open-source, Linux-only
- **Postman**: Cross-platform, Electron-based, cloud sync, team features
Roster focuses on being a simple, fast, native GNOME experience.
### How is Roster different from Insomnia?
Similar to Postman comparison. Roster is native GNOME with no cloud dependencies.
Roster is a lightweight, native GNOME application focused on simplicity. Unlike Postman/Insomnia (Electron-based with cloud features), Roster is Linux-only with no cloud dependencies.
### How is Roster different from HTTPie?
- **Roster**: GUI application with project management
- **HTTPie**: Command-line tool
Roster provides a visual interface while HTTPie is CLI-focused.
Roster provides a GUI with project management, while HTTPie is a command-line tool.
## Still Have Questions?

@ -10,23 +10,9 @@ After [[Installation]], launch Roster from:
## Your First Request
### Step 1: Create a Project
### Step 1: Configure the Request
Projects help organize related requests (e.g., "GitHub API", "My App API").
1. Click the **hamburger menu** (three lines) in the top-left
2. Select **"New Project"**
3. Enter a name: `My First Project`
4. Click **"Create"**
### Step 2: Create a Request
1. Click the **"+"** button in the header bar
2. Or: **Ctrl+T** keyboard shortcut
A new request tab appears with default values.
### Step 3: Configure the Request
Roster starts with a new request tab.
**Set the URL:**
```
@ -34,30 +20,29 @@ https://api.github.com/users/octocat
```
**Set the Method:**
- Use the dropdown menu
- Default is `GET` (perfect for this example)
- Use the dropdown menu (default is `GET`)
**Add Headers (Optional):**
1. Click the **"Headers"** tab
2. Add a header:
- Key: `User-Agent`
- Value: `Roster/0.5.0`
- Value: `Roster/0.6.0`
### Step 4: Send the Request
### Step 2: Send the Request
Click the **"Send"** button (or press **Ctrl+Return**)
### Step 5: View the Response
### Step 3: View the Response
The response appears in the right panel:
**Status Line:**
```
200 OK (123 ms, 1.2 KB)
200 OK 123 ms 1.2 KB
```
**Response Headers:**
Click the **"Headers"** dropdown to view all response headers.
Click the **"Headers"** tab to view all response headers.
**Response Body:**
The JSON response from GitHub API showing user information.
@ -67,6 +52,7 @@ The JSON response from GitHub API showing user information.
### Save for Later
1. Click the **"Save"** button in the header
2. Select project
2. Enter a name: `Get GitHub User`
3. Click **"Save"**
@ -74,7 +60,7 @@ The request is now saved to your project.
### Access Saved Requests
1. Click the **hamburger menu**
1. Click the project
2. Your project shows saved requests
3. Click a request to open it in a new tab
@ -83,15 +69,10 @@ The request is now saved to your project.
Every request you send is automatically saved to history.
**View History:**
1. Click the **"History"** button in the header bar
1. Navigate to bottom history panel
2. Browse past requests
3. Click any entry to open it in a new tab
**History includes:**
- Request details (URL, method, headers, body)
- Response details (status, headers, body, timing)
- Timestamp
## Working with Tabs
### Multiple Tabs
@ -105,46 +86,6 @@ Open multiple requests simultaneously:
Unsaved changes are marked with a dot (•) on the tab label.
## Next Example: POST Request
Let's send some data to an API.
### Step 1: New Request
Create a new request tab (**Ctrl+T**)
### Step 2: Configure POST Request
**URL:**
```
https://httpbin.org/post
```
**Method:**
```
POST
```
**Headers:**
```
Content-Type: application/json
```
**Body:**
1. Click the **"Body"** tab
2. Select **"JSON"** syntax highlighting
3. Enter JSON data:
```json
{
"name": "Test User",
"email": "test@example.com"
}
```
### Step 3: Send and View
Click **"Send"** and view the response. httpbin.org echoes back your request data.
## Common Request Types
### GET Request
@ -183,35 +124,19 @@ Body: (none)
### Syntax Highlighting
Roster automatically detects and highlights:
- **JSON** responses
- **XML** responses
- **HTML** responses
Roster automatically detects and highlights JSON, XML, and HTML responses.
### Response Timing
### Response Metrics
View how long the request took:
The status line shows status code, response time, and total size including headers:
```
200 OK (1.23 seconds, 5.4 KB)
200 OK 123 ms 5.4 KB
```
### Response Size
The status line shows the total response size including headers.
## Keyboard Shortcuts
Essential shortcuts to speed up your workflow:
| Action | Shortcut |
|--------|----------|
| New request | **Ctrl+T** |
| Send request | **Ctrl+Return** |
| Close tab | **Ctrl+W** |
| Save request | **Ctrl+S** |
| Switch tabs | **Ctrl+Tab** |
| Quit | **Ctrl+Q** |
See [[Keyboard-Shortcuts]] for the complete list.
## Next Steps
@ -226,20 +151,6 @@ Now that you know the basics, explore more advanced features:
## Tips
**Tip 1: Use httpbin.org for testing**
- `https://httpbin.org/get` - Test GET requests
- `https://httpbin.org/post` - Test POST requests
- `https://httpbin.org/headers` - See your request headers
- `https://httpbin.org/delay/3` - Test timeouts
**Tip 2: Save frequently used requests**
- Save requests to projects for quick access
- Use descriptive names: "Login", "Get User Profile", etc.
**Tip 3: Use syntax highlighting**
- Select JSON/XML/RAW in the body dropdown
- Makes reading requests and responses much easier
**Tip 4: Check the history**
- History persists across sessions
- Great for debugging or comparing responses
- Use `httpbin.org` endpoints for testing (e.g., `https://httpbin.org/get`)
- Save frequently used requests with descriptive names
- Check history panel to review and compare past responses

22
Home.md

@ -4,18 +4,13 @@ Welcome to the **Roster** documentation! Roster is a modern HTTP client for GNOM
## What is Roster?
Roster is a native GNOME application for testing and debugging HTTP APIs. It provides a clean, intuitive interface for:
Roster is a native GNOME application for testing and debugging HTTP APIs with support for:
- HTTP Requests - Send GET, POST, PUT, DELETE requests
- Custom Headers & Bodies - Full control over request configuration
- Response Viewing - View headers, body, status, and timing
- Request History - Persistent history with full request/response data
- Project Organization - Organize requests into projects
- Environment Variables - Manage different environments (dev, staging, prod)
- Sensitive Variables - Secure storage of API keys and tokens in GNOME Keyring
- JavaScript Scripts - Automate workflows with preprocessing/postprocessing
- Export - Export requests to cURL and other formats
- Beautiful UI - Native GNOME experience with libadwaita
- HTTP requests (GET, POST, PUT, DELETE) with custom headers and bodies
- Project organization with environment variables
- Secure credential storage using GNOME Keyring
- JavaScript preprocessing and postprocessing scripts
- Request history and export to cURL
## Quick Links
@ -36,11 +31,6 @@ Roster is a native GNOME application for testing and debugging HTTP APIs. It pro
- [[Keyboard-Shortcuts]] - Speed up your workflow
- [[FAQ]] - Frequently asked questions
### Development
- [[Contributing]] - How to contribute to Roster
- [[Development]] - Developer documentation
- [[Architecture]] - Technical overview
## Key Features
### Secure Credential Storage

@ -32,16 +32,12 @@ This method builds and installs Roster directly on your system.
**Fedora:**
```bash
sudo dnf install meson ninja-build gtk4-devel libadwaita-devel \
libsoup3-devel libsecret-devel gjs python3 \
gettext desktop-file-utils appstream
sudo dnf install meson ninja-build gtk4-devel libadwaita-devel libsoup3-devel libsecret-devel gjs python3 gettext desktop-file-utils appstream
```
**Ubuntu/Debian:**
```bash
sudo apt install meson ninja-build libgtk-4-dev libadwaita-1-dev \
libsoup-3.0-dev libsecret-1-dev gjs python3 \
gettext desktop-file-utils appstream
sudo apt install meson ninja-build libgtk-4-dev libadwaita-1-dev libsoup-3.0-dev libsecret-1-dev gjs python3 gettext desktop-file-utils appstream
```
**Arch Linux:**
@ -176,35 +172,17 @@ flatpak uninstall cz.bugsy.roster
## Troubleshooting
### Build Errors
**Build errors:**
- "meson: command not found" → Install Meson
- "Package not found" errors → Install missing development packages
**Error: "meson: command not found"**
- Install Meson build system (see dependencies above)
**Runtime errors:**
- "Failed to access Secret Service" → Ensure GNOME Keyring is unlocked
- "Module 'gi' not found" → Install PyGObject
**Error: "Package 'gtk4' not found"**
- Install GTK 4 development files (see dependencies above)
**Error: "Package 'libadwaita-1' not found"**
- Install libadwaita development files (see dependencies above)
### Runtime Errors
**Error: "Failed to access Secret Service"**
- Ensure GNOME Keyring is installed and unlocked
- For Flatpak: Check that D-Bus permission is granted
**Error: "Module 'gi' not found"**
- Ensure PyGObject is installed: `sudo dnf install python3-gobject`
### Flatpak Specific
**Error: "error: Nothing matches org.gnome.Platform"**
- Add Flathub remote: `flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo`
- Install GNOME SDK: `flatpak install flathub org.gnome.Platform//49 org.gnome.Sdk//49`
**Application doesn't have network access**
- Check Flatpak permissions: `flatpak info --show-permissions cz.bugsy.roster`
- Should include: `--share=network`
**Flatpak:**
- "Nothing matches org.gnome.Platform" → Add Flathub remote and install GNOME SDK
- No network access → Verify `--share=network` permission
## Next Steps

@ -19,10 +19,9 @@ Example projects:
### Creating a Project
1. Click the **hamburger menu** (three lines) in top-left
2. Select **"New Project"**
3. Enter project name
4. Click **"Create"**
1. Click the "+" icon in top-left
2. Enter project name
3. Click **"Create"**
A default "Default" environment is automatically created.
@ -33,11 +32,11 @@ Projects appear in the sidebar on the left side:
- Shows saved requests within the project
- Active project highlighted
### Renaming a Project
### Editing a Project
1. Right-click the project in sidebar
2. Select **"Rename"**
3. Enter new name
1. Click the "three-dots" symbol near the project name in sidebar
2. Select **"Edit Project"**
3. Enter new name or click icon to choose from grid
4. Click **"Save"**
### Deleting a Project
@ -48,13 +47,6 @@ Projects appear in the sidebar on the left side:
**Warning:** This deletes all requests, environments, and variables in the project!
### Changing Project Icon
1. Right-click the project in sidebar
2. Select **"Change Icon"**
3. Choose icon from grid
4. Icon updates immediately
## Environments
### What is an Environment?
@ -71,7 +63,8 @@ See [[Variables]] for complete environment and variable management documentation
**Quick access:**
1. Select a project
2. Click **"Environments"** button in header bar
2. Click the "three-dots" symbol near the project name in sidebar
3. Click **"Manage Environments"
3. Manage environments and variables in dialog
### Default Environment
@ -88,138 +81,31 @@ Each project starts with a "Default" environment. You can:
1. Configure your request (URL, method, headers, body)
2. Click **"Save"** button in header
3. Enter request name (e.g., "Get User Profile")
4. Click **"Save"**
Request is now saved to the current project.
4. Select a project
5. Click **"Save"**
### Opening a Saved Request
1. Click the hamburger menu
2. Navigate to your project
3. Click on a saved request
4. Request opens in a new tab
1. Navigate to your project
2. Click on a saved request
3. Request opens in a new tab
### Editing a Saved Request
1. Open the request
2. Make changes
3. Click **"Save"** (or Ctrl+S)
4. Changes are saved
4. Select Project and enter request name
5. Click Save
**Modified indicator:** Unsaved changes show a dot (•) on the tab label.
### Deleting a Saved Request
1. Right-click the request in sidebar
2. Select **"Delete"**
3. Confirm deletion
1. Click "x" icon near the request name in sidebar
2. Confirm deletion
### Attaching Scripts
See [[Scripts]] for complete documentation.
1. Save a request first
2. Right-click the request in sidebar
3. Select **"Edit Scripts"**
4. Write preprocessing/postprocessing scripts
5. Click **"Save"**
## Switching Between Projects
### In Sidebar
Simply click different projects in the sidebar to view their contents.
### Request Association
Each request tab remembers its project:
- Variables come from that project's environments
- Saving updates that project
## Organization Tips
### Group by Service
Create separate projects for each external API:
```
Projects:
GitHub API
- List Repositories
- Create Issue
- Get User
Stripe API
- Create Customer
- Create Payment
- List Charges
```
### Group by Feature
Create projects for features in your app:
```
Projects:
Authentication
- Login
- Logout
- Refresh Token
User Management
- Create User
- Update Profile
- Delete Account
```
### Use Descriptive Names
**Good request names:**
- "Login with Email/Password"
- "Get User Profile by ID"
- "Create Payment Intent (Stripe)"
- "Update User Settings"
**Bad request names:**
- "Request 1"
- "Test"
- "New Request"
- "GET"
## Project Workflow Example
### Step 1: Create Project
Create "My API" project
### Step 2: Add Environments
Open Environments dialog, add:
- Production
- Development
### Step 3: Define Variables
Add variables:
- `base_url`
- Production: `https://api.example.com`
- Development: `http://localhost:3000`
- `api_key` (mark as sensitive)
- Production: `prod-key-***`
- Development: `dev-key-***`
### Step 4: Create Requests
Create and save requests:
- "Get Users" - `GET {{base_url}}/users`
- "Create User" - `POST {{base_url}}/users`
- "Delete User" - `DELETE {{base_url}}/users/{{user_id}}`
### Step 5: Test Different Environments
1. Open "Get Users" request
2. Select "Development" environment
3. Send (hits localhost)
4. Select "Production" environment
5. Send (hits production API)
Same request, different targets!
Requests can have preprocessing and postprocessing scripts attached. See [[Scripts]] for details.
## Data Storage

@ -38,31 +38,21 @@ Use cases:
## Adding Scripts to Requests
### Step 1: Save a Request
### Step 1: Open Script Editor
Scripts are attached to saved requests.
Use the Scripts tab in the request editor
1. Configure your request
2. Click **"Save"** button
3. Enter request name
4. Click **"Save"**
The script editor tab contains two panels:
- **Preprocessing** panel
- **Postprocessing** panel
### Step 2: Open Script Editor
### Step 2: Write Your Script
1. Right-click the saved request in the sidebar
2. Select **"Edit Scripts"**
3. Script editor dialog opens with two tabs:
- **Preprocessing** tab
- **Postprocessing** tab
### Step 3: Write Your Script
1. Select the appropriate tab
1. Select the appropriate panel
2. Write JavaScript code
3. Click **"Save"** or **Ctrl+S**
4. Close dialog
### Step 4: Run Request with Scripts
### Step 3: Run Request with Scripts
1. Open the request
2. Click **"Send"**
@ -386,105 +376,33 @@ if (suggestedVersion) {
## Script Execution Flow
When you click "Send" on a request with scripts:
```
1. Load request from UI
2. IF preprocessing script exists:
2a. Execute preprocessing script
2b. Script can modify request object
2c. Script output shown in "Preprocessing" tab
3. Apply variable substitution ({{variable_name}})
4. Send HTTP request
5. Receive response
6. IF postprocessing script exists:
6a. Execute postprocessing script
6b. Script can read response, set variables
6c. Script output shown in "Postprocessing" tab
7. Display response in UI
8. Save to history
```
When sending a request with scripts:
1. Execute preprocessing script (if present) - can modify request
2. Apply variable substitution (`{{variable_name}}`)
3. Send HTTP request
4. Execute postprocessing script (if present) - can read response, set variables
5. Display response and save to history
## Error Handling
### Script Errors
If a script throws an error:
- Error message shown in script results tab
- Request still executes (preprocessing) or response still displays (postprocessing)
- Variable changes before the error are preserved
### Example: Safe JSON Parsing
If a script throws an error, the error is shown in the script output panel. The request still executes (preprocessing) or response still displays (postprocessing). Variable changes before the error are preserved.
Always use try-catch for JSON parsing:
```javascript
try {
const data = JSON.parse(response.body);
roster.setVariable('user_id', data.user.id);
console.log('Success');
} catch (e) {
console.error('Failed to parse JSON:', e.message);
console.error('Parse error:', e.message);
}
```
## Best Practices
### Keep Scripts Simple
Scripts should be short and focused:
- One clear purpose per script
- Avoid complex logic
- Use console.log for debugging
### Error Handling
Always handle potential errors:
```javascript
if (response.statusCode === 200) {
try {
const data = JSON.parse(response.body);
// ... process data
} catch (e) {
console.error('Parse error:', e.message);
}
} else {
console.error('Request failed:', response.statusText);
}
```
### Variable Naming
Use clear, descriptive variable names:
```javascript
// Good
roster.setVariable('github_access_token', token);
roster.setVariable('user_profile_id', id);
// Bad
roster.setVariable('token', token);
roster.setVariable('id', id);
```
### Logging
Use console output to track script execution:
```javascript
console.log('Starting authentication...');
// ... authentication logic
console.log('Authentication complete');
```
### Sensitive Data
**Never log sensitive data:**
```javascript
// BAD - logs the actual token
const token = roster.getVariable('api_key');
console.log('Token:', token);
// GOOD - confirms without revealing
const token = roster.getVariable('api_key');
console.log('Token retrieved');
```
- **Keep scripts simple** - One clear purpose per script
- **Handle errors** - Use try-catch for JSON parsing and check status codes
- **Use logging** - Track execution with console.log for debugging
- **Never log secrets** - Log confirmations, not actual token/key values
## Limitations
@ -513,37 +431,9 @@ Scripts cannot:
## Debugging Scripts
### Use Console Output
Liberally use console.log:
```javascript
console.log('Request URL before:', request.url);
// ... modify URL
console.log('Request URL after:', request.url);
```
### Check Script Results
After sending request:
1. Look for "Preprocessing" tab (if preprocessing script exists)
2. Look for "Postprocessing" tab (if postprocessing script exists)
3. View console output and any errors
### Test with Simple Scripts
Start simple and build up:
```javascript
// Test 1: Verify script runs
console.log('Script is running!');
// Test 2: Verify variable access
const baseUrl = roster.getVariable('base_url');
console.log('Base URL:', baseUrl);
// Test 3: Verify request modification
request.headers['X-Test'] = 'hello';
console.log('Added test header');
```
- Use console.log liberally to track script execution
- Check Preprocessing/Postprocessing panels for output and errors
- Start with simple test scripts and build up complexity
## Next Steps

@ -36,41 +36,29 @@ Content: "secret-abc123-visible-to-all" (encrypted at rest)
## Usage
### Step 1: Open Environments Dialog
### Mark Variable as Sensitive
1. Select your project from the sidebar
2. Click the **"Environments"** button in the header bar
3. The variables table appears
Open the Environments dialog for your project.
### Step 2: Identify the Lock Icon
Each variable row has three buttons:
- Variable name entry
- **Lock icon** (toggle between secure/insecure storage)
- Delete button (trash icon)
### Step 3: Mark Variable as Sensitive
Each variable row has a **lock icon** to toggle between secure/insecure storage.
**Before entering secrets (recommended):**
1. Create variable (e.g., `api_key`)
2. Click the **lock icon** (appears as unlocked/gray initially)
3. Icon changes to locked state (with accent color)
4. Variable name becomes bold and colored
5. Now enter your secret value
2. Click the **lock icon** - it changes to locked state
3. Variable name becomes bold and colored
4. Enter your secret value
**After entering secrets (migration):**
1. Click the lock icon on existing variable
2. Values automatically move from JSON to keyring
3. JSON file now contains empty placeholders
### Step 4: Enter Secret Values
### Enter Secret Values
1. Click in the value entry field
2. Type your secret value
3. **You'll see bullets (••••••) instead of characters**
4. Value automatically saves to GNOME Keyring (encrypted)
Values in sensitive variables:
- Display as bullets (••••••) instead of characters
- Automatically save to GNOME Keyring (encrypted)
### Step 5: Use in Requests
### Use in Requests
Sensitive variables work exactly like regular variables:
@ -85,62 +73,11 @@ When you send the request:
3. Substitutes it into the request
4. Sends the request with the real value
## Visual Indicators
### Lock Icon States
**Unlocked (channel-insecure-symbolic):**
- Gray/inactive appearance
- Variable stored in plain JSON
- Tooltip: "Not sensitive (stored in JSON) - Click to mark as sensitive"
**Locked (channel-secure-symbolic):**
- Colored/active appearance (accent color)
- Variable stored in encrypted keyring
- Tooltip: "Sensitive (stored in keyring) - Click to make non-sensitive"
### Variable Name Styling
**Regular variables:**
- Normal text color
- Normal font weight
**Sensitive variables:**
- Accent color (theme-dependent)
- Bold font weight
- Easy to identify at a glance
### Value Entry Fields
**Regular variables:**
- Show typed characters normally
- Standard text entry
**Sensitive variables:**
- Show bullets (••••••) like password fields
- Entry purpose: PASSWORD
- Cannot see the value while typing
## Viewing Secrets in Keyring
To verify your secrets are encrypted:
Open "Passwords and Keys" (Seahorse) and navigate to "Login" keyring. Look for entries labeled `Roster: ProjectName/EnvironmentName/VariableName`.
1. Open **"Passwords and Keys"** application (Seahorse)
2. Navigate to **"Login"** keyring
3. Look for entries labeled: `Roster: ProjectName/EnvironmentName/VariableName`
Example:
```
Login Keyring
Roster: GitHub API/Production/api_token
Roster: GitHub API/Development/api_token
Roster: Stripe API/Production/secret_key
```
Click any entry to:
- View the secret value (requires authentication)
- Edit the value manually
- Delete the secret
You can view, edit, or delete secrets from Seahorse (requires authentication).
## Making Variables Non-Sensitive
@ -155,92 +92,14 @@ If you marked a variable as sensitive by mistake:
## Security
### Encryption
- Values encrypted at rest with your GNOME login password
- Uses same encryption as system passwords
- No plaintext secrets in file system
### Auto-Unlock
- Keyring unlocks automatically when you log in
- No need to enter password again
- Locked when you log out
### Access Control
- Only your user account can access
- Protected by OS-level security
- Sandboxed apps (Flatpak) require explicit permission
### Separation
Roster secrets are stored with a custom schema:
- Schema: `cz.bugsy.roster.EnvironmentVariable`
- Attributes: `project_id`, `environment_id`, `variable_name`
- **Won't clutter your personal passwords**
- Easy to identify in Seahorse
## Best Practices
### DO Mark as Sensitive
- **API keys**: `api_key`, `github_token`, `stripe_key`
- **Passwords**: `password`, `db_password`, `admin_pass`
- **Tokens**: `bearer_token`, `oauth_token`, `access_token`
- **Secrets**: `client_secret`, `api_secret`, `webhook_secret`
- **Private keys**: Any cryptographic keys
### DON'T Mark as Sensitive
- **URLs**: `base_url`, `api_endpoint`, `webhook_url`
- **Configuration**: `timeout`, `max_retries`, `api_version`
- **Identifiers**: `env`, `region`, `datacenter`, `tenant_id`
- **Non-secret data**: Anything that's OK to be visible
### Workflow Tips
**Create variables first, then mark as sensitive:**
```
1. Add variable "api_key"
2. Click lock icon (mark as sensitive)
3. Enter value (goes to keyring immediately)
```
**Use descriptive names:**
```
Good: github_personal_token, stripe_secret_key
Bad: token1, key, secret
```
**Group related variables:**
```
base_url (regular)
api_key (sensitive)
api_secret (sensitive)
timeout (regular)
```
- Encrypted at rest with your GNOME login password
- Keyring unlocks automatically on login
- Only accessible by your user account
- Flatpak requires explicit permission
## Automatic Cleanup
When you delete variables, environments, or projects, Roster automatically cleans up keyring secrets:
**Delete variable:**
- Removed from JSON
- All keyring secrets for that variable deleted (across all environments)
**Delete environment:**
- Removed from JSON
- All keyring secrets for that environment deleted
**Delete project:**
- Project removed from disk
- **All keyring secrets for that project deleted**
**Rename variable:**
- Variable renamed in JSON
- All keyring secrets automatically renamed
- No data loss
Roster automatically removes keyring secrets when you delete variables, environments, or projects. Renamed variables are also automatically updated in the keyring.
## Script Integration
@ -270,105 +129,22 @@ Scripts don't need to know whether variables are sensitive - storage is handled
## Troubleshooting
### Keyring Not Unlocked
**Keyring not unlocked:**
- Ensure you're logged into GNOME (keyring unlocks automatically)
- Manual unlock: Open Seahorse, right-click "Login", select "Unlock"
**Symptom:** Error accessing secrets
**Flatpak permission denied:**
- Verify `cz.bugsy.roster.json` includes `--talk-name=org.freedesktop.secrets`
- Check: `flatpak info --show-permissions cz.bugsy.roster`
**Solution:**
1. Ensure you're logged into GNOME
2. Keyring unlocks automatically on login
3. Manual unlock: Open "Passwords and Keys", right-click "Login", select "Unlock"
**Secrets missing after reinstall:**
- Keyring persists across installs - check Seahorse under "Login" keyring
### Flatpak Permission Denied
## Platform Notes
**Symptom:** Cannot access keyring from Flatpak
Both native and Flatpak installations use the same system keyring. Secrets work across install methods.
**Solution:**
1. Check `cz.bugsy.roster.json` includes: `--talk-name=org.freedesktop.secrets`
2. Rebuild Flatpak with correct permissions
3. Verify: `flatpak info --show-permissions cz.bugsy.roster`
### Cannot View Secret in Seahorse
**Symptom:** Secret exists but won't display
**Solution:**
1. Right-click the secret in Seahorse
2. Select "Show password"
3. Enter your login password when prompted
### Lost Secrets After Reinstall
**Symptom:** Secrets missing after reinstalling Roster
**Keyring persists across installs** - secrets should still be there.
**Check:**
1. Open Seahorse
2. Look under "Login" keyring
3. Search for "Roster:"
If missing, you'll need to re-enter them.
## Advanced: Manual Keyring Management
You can manually manage Roster secrets using Seahorse:
### View All Roster Secrets
1. Open Seahorse
2. Navigate to "Login" keyring
3. Search or filter for: `Roster`
4. All Roster secrets appear
### Backup Secrets
Seahorse can export keyring for backup:
1. File → Export
2. Select secrets to export
3. Choose secure location
### Delete All Roster Secrets
1. Search for "Roster" in Seahorse
2. Select all Roster entries
3. Right-click → Delete
## Migration from Plain Variables
If you have existing projects with secrets in plain text:
```javascript
// Step 1: Identify secrets in your variables
// Look for: api_key, password, token, secret, private_key
// Step 2: For each secret variable:
// - Open Environments dialog
// - Click lock icon
// - Values automatically move to keyring
// Step 3: Verify in Seahorse
// - Open "Passwords and Keys"
// - Check secrets appear under "Login" keyring
```
Your JSON file will now have empty strings, and secrets are encrypted.
## Platform Differences
### Native Installation
- Keyring: `~/.local/share/keyrings/`
- Direct access to system keyring
- No special permissions needed
### Flatpak Installation
- Keyring: Same system keyring (shared)
- Requires D-Bus permission: `--talk-name=org.freedesktop.secrets`
- Sandboxed but can access keyring with permission
Both installations share the same keyring - secrets work across install methods!
Flatpak requires D-Bus permission: `--talk-name=org.freedesktop.secrets`
## Next Steps

@ -34,11 +34,12 @@ Each project can have multiple environments, and each environment has its own se
### Step 1: Open Environments Dialog
1. Select a project from the sidebar
2. Click the **"Environments"** button in the header bar
2. Click the "Three-Dots" button near the project name
3. Select **"Manage Environments"**
### Step 2: Add Environment
1. Click **"Add Environment"** button
1. Click **+** button near Environments
2. Enter name (e.g., "Production", "Development")
3. Click **"Add"**
@ -61,7 +62,7 @@ Click in the cells to enter values for each environment:
| base_url | `https://api.example.com` | `http://localhost:3000` |
| timeout | `30` | `60` |
Click **"Done"** to save.
Close Manage Environments table to save.
## Using Variables in Requests
@ -93,17 +94,16 @@ Variables work in:
### Rename Variable
1. Open **Environments** dialog
1. Open **Manage Environments** dialog
2. Click on variable name
3. Edit the name
4. Press Enter
The variable is renamed across all environments automatically.
### Delete Variable
1. Open **Environments** dialog
2. Click the **trash icon** next to variable name
2. Click the **x** next to variable name
3. Confirm deletion
The variable is removed from all environments.
@ -127,55 +127,12 @@ All variable values for that environment are deleted.
## Common Variable Patterns
### Base URL
```
Variable: base_url
Production: https://api.example.com
Development: http://localhost:3000
Usage: {{base_url}}/users/123
```
### API Version
```
Variable: api_version
Production: v2
Development: v2-beta
Usage: {{base_url}}/{{api_version}}/users
```
### Timeout Values
```
Variable: timeout
Production: 30
Development: 60
Usage: X-Timeout: {{timeout}}
```
### Environment Identifier
```
Variable: env
Production: prod
Development: dev
Usage: X-Environment: {{env}}
```
### User ID for Testing
```
Variable: test_user_id
Production: 12345
Development: 1
Usage: {{base_url}}/users/{{test_user_id}}
```
Common variables to define across environments:
- `base_url` - API base URL (e.g., `https://api.example.com` vs `http://localhost:3000`)
- `api_version` - API version (e.g., `v2` vs `v2-beta`)
- `timeout` - Request timeout values
- `env` - Environment identifier for headers
- `test_user_id` - Test data IDs
## Script Integration
@ -231,123 +188,26 @@ Scripts automatically update variables in the currently selected environment.
## Best Practices
### Use Descriptive Names
Good:
- `base_url`
- `api_key`
- `github_token`
- `stripe_secret_key`
Bad:
- `url1`
- `key`
- `token`
### Group Related Variables
```
# API Configuration
base_url
api_version
timeout
# Authentication
api_key
api_secret
auth_token
# Test Data
test_user_id
test_email
```
### Keep Environments Consistent
All environments should have the same variable names with different values:
| Variable | Production | Development |
|----------|-----------|-------------|
| base_url | `api.example.com` | `localhost:3000` |
| api_key | `prod-key-***` | `dev-key-***` |
| timeout | `30` | `60` |
### Use Sensitive Variables for Secrets
**DO NOT** store secrets in regular variables - they are saved in plain text!
Use [[Sensitive-Variables]] instead:
- API keys
- Passwords
- Tokens
- Secret keys
- **Keep environments consistent** - All environments should have the same variable names with different values
- **Use sensitive variables for secrets** - Never store API keys, passwords, or tokens in regular variables (they're plain text). Use [[Sensitive-Variables]] instead
## Undefined Variables
When Roster encounters `{{variable_name}}` but the variable is not defined:
When `{{variable_name}}` is not defined in the current environment:
- Entry field is highlighted with warning color
- The literal text `{{variable_name}}` is sent in the request
**Visual Warning:**
- The entry field with undefined variable is highlighted
- Warning color indicates missing variable
**Request Behavior:**
- The literal text `{{variable_name}}` is sent
- No error is thrown
- Check the console for warnings
**Fix:**
1. Open **Environments** dialog
2. Add the missing variable
3. Set its value in current environment
To fix, add the variable in the Environments dialog.
## Environment Switching
Switch environments to test the same request against different APIs:
**Example Workflow:**
1. Create request: `GET {{base_url}}/users`
2. Select "Development" environment
3. Send request (goes to `http://localhost:3000/users`)
4. Select "Production" environment
5. Send request (goes to `https://api.example.com/users`)
Same request, different targets!
Use the environment dropdown to test the same request against different targets. For example, `GET {{base_url}}/users` will hit `localhost:3000/users` in Development or `api.example.com/users` in Production.
## Advanced Topics
### Variables in Request Body
```json
{
"api_key": "{{api_key}}",
"environment": "{{env}}",
"user_id": {{user_id}}
}
```
Note: Numeric values should not have quotes if you want them as numbers.
### Nested Variable References
Variables can contain other variables:
```
Variable: full_url
Value: {{base_url}}/{{api_version}}/users
```
Both `{{base_url}}` and `{{api_version}}` will be substituted.
### Dynamic Variables from Scripts
Variables don't have to be manually created - scripts can create them:
```javascript
// Preprocessing script
const timestamp = new Date().toISOString();
roster.setVariable('request_timestamp', timestamp);
// Now you can use {{request_timestamp}} in the request
```
- **Variables in JSON body** - Use `{{variable}}` syntax. Remove quotes for numeric values
- **Nested variables** - Variables can reference other variables (e.g., `{{base_url}}/{{api_version}}`)
- **Script-created variables** - Scripts can create variables with `roster.setVariable()`
## Next Steps