Commit Graph

171 Commits

Author SHA1 Message Date
Shaun Arman
abab5c3153 fix(security): enforce PII redaction before AI log transmission
analyze_logs() was reading the original log file from disk and sending its
full contents to external AI providers, completely bypassing the redaction
pipeline. The redacted flag in log_files and the .redacted file on disk were
written by apply_redactions() but never consulted on the read path.

Fix: query the redacted column alongside file_path. If the file has not been
redacted, return an error to the caller before any AI provider call is made.
When redacted, read from {path}.redacted instead of the original.

Adds redacted_path_for() helper and two unit tests covering the rejection
and happy-path cases.
2026-04-05 10:08:16 -05:00
Shaun Arman
0a25ca7692 fix(pii): remove lookahead from hostname regex, fix fmt in analysis test
Rust's `regex` crate does not support lookaround assertions. The hostname
pattern `(?=.{1,253}\b)` caused a panic on every `PiiDetector::new()` call,
failing all four PII detector tests in CI (rust-fmt-check, rust-clippy,
rust-tests). Removed the lookahead; the remaining pattern correctly matches
valid FQDNs without the RFC 1035 length pre-check.

Also reformatted analysis.rs:253 to satisfy `rustfmt` (line break after `=`).

All 127 Rust tests pass and `cargo fmt --check` and `cargo clippy -- -D
warnings` are clean.
2026-04-05 09:59:19 -05:00
Shaun Arman
281e676ad1 fix(security): harden secret handling and audit integrity
Remove high-risk defaults and tighten data handling across auth, storage, IPC, provider calls, and capabilities so sensitive data is better protected by default. Also update README/wiki security guidance and add targeted tests for the new hardening behaviors.

Made-with: Cursor
2026-04-04 23:37:05 -05:00
Shaun Arman
b1d794765f fix(ci): unblock release jobs and namespace linux artifacts by arch
Drop fragile job-condition gates that were blocking release jobs, and upload linux artifacts with arch-prefixed release asset names so amd64 and arm64 outputs can coexist even when bundle filenames are identical.

Made-with: Cursor
2026-04-04 23:17:12 -05:00
Shaun Arman
7b5f2daaa4 fix(ci): run linux arm release natively and enforce arm artifacts
Avoid cross-compiling GTK/glib on the arm release job by building natively on ARM64 hosts, add an explicit architecture guard, and restrict uploads to arm64/aarch64 artifact filenames so amd64 outputs cannot be published as arm releases.

Made-with: Cursor
2026-04-04 22:46:23 -05:00
Shaun Arman
aaa48d65a2 fix(ci): force explicit linux arm64 target for release artifacts
Build linux arm64 bundles with --target aarch64-unknown-linux-gnu and upload from the target-specific bundle path so arm64 releases cannot accidentally publish amd64 artifacts.

Made-with: Cursor
2026-04-04 22:15:02 -05:00
Shaun Arman
e20228da6f refactor(ci): remove standalone release workflow
Delete .gitea/workflows/release.yml and keep release orchestration in auto-tag.yml only, then update related workflow tests and docs to reference the unified pipeline.

Made-with: Cursor
2026-04-04 21:34:15 -05:00
Shaun Arman
2d2c62e4f5 fix(ci): repair auto-tag workflow yaml so jobs trigger
Replace heredoc-based Python error logging with single-line python invocations to keep YAML block indentation valid, restoring Gitea's ability to parse and trigger auto-tag plus downstream release build jobs.

Made-with: Cursor
2026-04-04 21:28:52 -05:00
Shaun Arman
b69c132a0a fix(ci): run post-tag release builds without job-output gating
Remove auto-tag job output dependencies and conditional gates so release build jobs always run after autotag completes, resolving skipped fan-out caused by output/if evaluation issues in Gitea Actions.

Made-with: Cursor
2026-04-04 21:24:24 -05:00
Shaun Arman
a6b4ed789c fix(ci): use stable auto-tag job outputs for release fanout
Rename the auto-tag job id to a non-hyphenated identifier and update needs/output references so dependent release jobs evaluate conditions correctly and reliably run after tagging.

Made-with: Cursor
2026-04-04 21:21:35 -05:00
Shaun Arman
93ead1362f fix(ci): guarantee release jobs run after auto-tag
Run linux/windows/macos/arm release build and upload jobs in the auto-tag workflow with needs:auto-tag outputs so release execution no longer depends on a second tag-triggered workflow dispatch path.

Made-with: Cursor
2026-04-04 21:19:13 -05:00
Shaun Arman
48041acc8c fix(ci): trigger release workflow from auto-tag pushes
Switch auto-tag to create and push tags via git instead of the tag API so Gitea emits a real tag push event that reliably starts release builds. Document the trigger behavior and add a workflow regression test.

Made-with: Cursor
2026-04-04 21:14:41 -05:00
42120cb140 Merge pull request 'fix(ci): harden release asset uploads for reruns' (#7) from fix/release-upload-rerun-hardening into master
Reviewed-on: #7
2026-04-05 02:10:54 +00:00
Shaun Arman
2d35e2a2c1 fix(ci): harden release asset uploads for reruns
Make all release upload steps fail fast when expected artifacts are missing, replace existing same-name assets before uploading, and print HTTP/body details on upload failures so Linux/Windows publishing issues are diagnosable and reruns remain deterministic.

Made-with: Cursor
2026-04-04 21:09:03 -05:00
b22d508f25 Merge pull request 'fix(ci): stabilize release artifacts for windows and linux' (#6) from fix/release-windows-openssl-linux-assets into master
Some checks failed
Release / build-macos-arm64 (push) Has been cancelled
Release / build-linux-arm64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
Reviewed-on: #6
2026-04-05 01:21:31 +00:00
Shaun Arman
c3fd83f330 fix(ci): make release artifacts reliable across platforms
Override OpenSSL vendoring for the windows-gnu release build so cross-compiles no longer fail on pkg-config lookup, and fail fast when Linux release jobs produce no artifacts so incomplete releases are detected immediately.

Made-with: Cursor
2026-04-04 19:53:40 -05:00
4606fdd104 Merge pull request 'ci: run test workflow only on pull requests' (#5) from fix/pr4-clean-replacement into master
Some checks failed
Release / build-linux-arm64 (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Release / build-macos-arm64 (push) Has been cancelled
Reviewed-on: #5
2026-04-05 00:14:07 +00:00
Shaun Arman
4e7a5b64ba ci: run test workflow only on pull requests
Avoid duplicate Test workflow executions by removing push triggers and keeping pull_request validation as the single gate. Also fix remaining clippy format string violations in integration modules to keep rust-clippy passing.

Made-with: Cursor
2026-04-04 18:52:13 -05:00
82c18871af Merge pull request 'fix/skip-master-test-workflow' (#3) from fix/skip-master-test-workflow into master
Some checks failed
Release / build-windows-amd64 (push) Has been cancelled
Release / build-macos-arm64 (push) Has been cancelled
Release / build-linux-arm64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Reviewed-on: #3
2026-04-04 21:48:47 +00:00
Shaun Arman
8e7356e62d ci: skip test workflow pushes on master
Avoid rerunning the full test workflow on direct master pushes while keeping pull request validation intact. Update the CI/CD wiki page to reflect the new trigger behavior.

Made-with: Cursor
2026-04-04 16:45:55 -05:00
Shaun Arman
b426f56149 fix: resolve macOS bundle path after app rename
Find the generated .app bundle dynamically in release CI so macOS packaging no longer depends on the legacy TFTSR.app name. Add a unit test to prevent regressions by asserting the old hardcoded path is not reintroduced.

Made-with: Cursor
2026-04-04 16:28:01 -05:00
f2531eb922 Merge pull request 'fix: resolve clippy uninlined_format_args (CI run 178)' (#2) from fix/clippy-uninlined-format-args into master
Some checks failed
Release / build-linux-arm64 (push) Has been cancelled
Release / build-macos-arm64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
Reviewed-on: #2
2026-04-04 21:08:52 +00:00
Shaun Arman
c4ea32e660 feat: add custom_rest provider mode and rebrand application name
Rename custom API format handling from custom_rest to custom_rest with backward compatibility, add guided model selection with custom entry in provider settings, and rebrand app naming to Troubleshooting and RCA Assistant across UI, metadata, and docs.

Made-with: Cursor
2026-04-04 15:35:58 -05:00
Shaun Arman
0bc20f09f6 style: apply rustfmt output for clippy-related edits
Apply canonical rustfmt formatting in files touched by the clippy format-args cleanup so cargo fmt --check passes consistently in CI.

Made-with: Cursor
2026-04-04 15:10:17 -05:00
Shaun Arman
85a8d0a4c0 fix: resolve clippy format-args failures and OpenSSL vendoring issue
Inline format arguments across Rust modules to satisfy clippy -D warnings, and configure Cargo to prefer system OpenSSL so clippy builds do not fail on missing vendored Perl modules.

Made-with: Cursor
2026-04-04 15:05:13 -05:00
Shaun Arman
bdb63f3aee fix: resolve clippy uninlined_format_args in integrations and related modules
Replace format!("msg: {}", var) with format!("msg: {var}") across 8 files
to satisfy the uninlined_format_args lint (-D warnings) in CI run 178.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 12:27:26 -05:00
Shaun Arman
64492c743b fix: ARM64 build uses native target instead of cross-compile
Some checks failed
Release / build-macos-arm64 (push) Successful in 5m14s
Release / build-linux-arm64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
The ARM64 build was failing because explicitly specifying
--target aarch64-unknown-linux-gnu on an ARM64 runner was
triggering cross-compilation logic.

Changes:
- Remove rustup target add (not needed for native build)
- Remove --target flag from cargo tauri build
- Update artifact path: target/aarch64-unknown-linux-gnu/release/bundle
  → target/release/bundle

This allows the native ARM64 toolchain to build without
attempting cross-compilation and avoids the pkg-config
cross-compilation configuration requirement.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-04 09:59:56 -05:00
Shaun Arman
a7903db904 fix: persist integration settings and implement persistent browser windows
Some checks failed
Release / build-macos-arm64 (push) Successful in 4m52s
Release / build-linux-amd64 (push) Has been cancelled
Release / build-linux-arm64 (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
## Integration Settings Persistence
- Add database commands to save/load integration configs (base_url, username, project_name, space_key)
- Frontend now loads configs from DB on mount and saves changes automatically
- Fixes issue where settings were lost on app restart

## Persistent Browser Window Architecture
- Integration browser windows now stay open for user browsing and authentication
- Extract fresh cookies before each API call to handle token rotation
- Track open windows in app state (integration_webviews HashMap)
- Windows titled as "{Service} Browser (TFTSR)" for clarity
- Support easy navigation between app and browser windows (Cmd+Tab/Alt+Tab)
- Gracefully handle closed windows with automatic cleanup

## Bug Fixes
- Fix Rust formatting issues across 8 files
- Fix clippy warnings:
  - Use is_some_and() instead of map_or() in openai.rs
  - Use .to_string() instead of format!() in integrations.rs
- Add missing OptionalExtension import for .optional() method

## Tests
- Add test_integration_config_serialization
- Add test_webview_tracking
- Add test_token_auth_request_serialization
- All 6 integration tests passing

## Files Modified
- src-tauri/src/state.rs: Add integration_webviews tracking
- src-tauri/src/lib.rs: Register 3 new commands, initialize webviews HashMap
- src-tauri/src/commands/integrations.rs: Config persistence, fresh cookie extraction (+151 lines)
- src-tauri/src/integrations/webview_auth.rs: Persistent window behavior
- src/lib/tauriCommands.ts: TypeScript wrappers for new commands
- src/pages/Settings/Integrations.tsx: Load/save configs from DB

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-04 09:57:22 -05:00
Shaun Arman
fbce897608 feat: complete webview cookie extraction implementation
Some checks failed
Release / build-macos-arm64 (push) Successful in 5m4s
Release / build-windows-amd64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Release / build-linux-arm64 (push) Has been cancelled
Implement working cookie extraction using Tauri's IPC event system:

**How it works:**
1. Opens embedded browser window for user to login
2. User completes authentication (including SSO)
3. User clicks "Complete Login" button in UI
4. JavaScript injected into webview extracts `document.cookie`
5. Parsed cookies emitted via Tauri event: `tftsr-cookies-extracted`
6. Rust listens for event and receives cookie data
7. Cookies encrypted and stored in database

**Technical implementation:**
- Uses `window.__TAURI__.event.emit()` from injected JavaScript
- Rust listens via `app_handle.listen()` with Listener trait
- 10-second timeout with clear error messages
- Handles empty cookies and JavaScript errors gracefully
- Cross-platform compatible (no platform-specific APIs)

**Cookie limitations:**
- `document.cookie` only exposes non-HttpOnly cookies
- HttpOnly session cookies won't be captured via JavaScript
- For HttpOnly cookies, services must provide API tokens as fallback

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-03 17:31:48 -05:00
Shaun Arman
32d83df3cf feat: add multi-mode authentication for integrations (v0.2.10)
Some checks failed
Release / build-windows-amd64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Release / build-macos-arm64 (push) Has been cancelled
Release / build-linux-arm64 (push) Has been cancelled
Implement three authentication methods for Confluence, ServiceNow, and Azure DevOps:

1. **OAuth2** - Traditional OAuth flow for enterprise SSO environments
2. **Embedded Browser** - Webview-based login that captures session cookies/tokens
   - Solves VPN constraints: users authenticate off-VPN via web UI
   - Extracted credentials work on-VPN for API calls
   - Based on confluence-publisher agent pattern
3. **Manual Token** - Direct API token/PAT input as fallback

**Changes:**
- Add webview_auth.rs module for embedded browser authentication
- Implement authenticate_with_webview and extract_cookies_from_webview commands
- Implement save_manual_token command with validation
- Add AuthMethod enum to support all three modes
- Add RadioGroup UI component for mode selection
- Complete rewrite of Integrations settings page with mode-specific UI
- Add secondary button variant for UI consistency

**VPN-friendly design:**
Users can authenticate via webview when off-VPN (web UI accessible), then use extracted cookies for API calls when on-VPN (API requires VPN). Addresses enterprise SSO limitations where OAuth app registration is blocked.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-03 17:26:09 -05:00
Shaun Arman
2c5e04a6ce feat: add temperature and max_tokens support for Custom REST providers (v0.2.9)
Some checks failed
Release / build-linux-amd64 (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
Release / build-macos-arm64 (push) Has been cancelled
Release / build-linux-arm64 (push) Has been cancelled
- Added max_tokens and temperature fields to ProviderConfig
- Custom REST providers now send modelConfig with temperature and max_tokens
- OpenAI-compatible providers now use configured max_tokens/temperature
- Both formats fall back to defaults if not specified
- Bumped version to 0.2.9

This allows users to configure response length and randomness for all
AI providers, including Custom REST providers which require modelConfig format.
2026-04-03 17:08:34 -05:00
Shaun Arman
1d40dfb15b fix: use Wiki secret for authenticated wiki sync (v0.2.8)
Some checks failed
Release / build-macos-arm64 (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
Release / build-linux-arm64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
- Updated wiki-sync job to use secrets.Wiki for authentication
- Simplified clone/push logic with token-based auth
- Wiki push will now succeed with proper credentials
- Bumped version to 0.2.8

The workflow now uses the 'Wiki' secret created in Gitea Actions
to authenticate wiki repository pushes. This fixes the authentication
issue that was preventing automatic wiki synchronization.
2026-04-03 16:47:32 -05:00
Shaun Arman
94b486b801 feat: add automatic wiki sync to CI workflow (v0.2.7)
- Added wiki-sync job to .gitea/workflows/test.yml
- Runs only on pushes to master branch
- Automatically copies docs/wiki/*.md to Gogs wiki repository
- Supports token-based authentication via secrets.GITHUB_TOKEN
- Handles wiki initialization if repository doesn't exist
- Bumped version to 0.2.7

Wiki sync will now automatically update the Gogs wiki at
https://gogs.tftsr.com/sarman/tftsr-devops_investigation/wiki
whenever docs/wiki/ files are modified on master.
2026-04-03 16:42:37 -05:00
Shaun Arman
5f9798a4fd docs: update wiki for v0.2.6 - integrations and Custom REST provider
Updated 5 wiki pages:

Home.md:
- Updated version to v0.2.6
- Added Custom REST provider and custom provider support to features
- Updated integration status from stubs to complete
- Updated release table with v0.2.3 and v0.2.6 highlights

Integrations.md:
- Complete rewrite: Changed from 'v0.2 stubs' to fully implemented
- Added detailed docs for Confluence REST API client (6 tests)
- Added detailed docs for ServiceNow REST API client (7 tests)
- Added detailed docs for Azure DevOps REST API client (6 tests)
- Documented OAuth2 PKCE flow implementation
- Added database schema for credentials and integration_config tables
- Added troubleshooting section with common OAuth/API errors

AI-Providers.md:
- Added section for Custom Provider (Custom REST provider)
- Documented Custom REST provider API format differences from OpenAI
- Added request/response format examples
- Added configuration instructions and troubleshooting
- Documented custom provider fields (api_format, custom_endpoint_path, etc)
- Added available Custom REST provider models list

IPC-Commands.md:
- Replaced 'v0.2 stubs' section with full implementation details
- Added OAuth2 commands (initiate_oauth, handle_oauth_callback)
- Added Confluence commands (5 functions)
- Added ServiceNow commands (5 functions)
- Added Azure DevOps commands (5 functions)
- Documented authentication storage with AES-256-GCM encryption
- Added common types (ConnectionResult, PublishResult, TicketResult)

Database.md:
- Updated migration count from 10 to 11
- Added migration 011: credentials and integration_config tables
- Documented AES-256-GCM encryption for OAuth tokens
- Added usage notes for OAuth2 vs basic auth storage
2026-04-03 16:39:49 -05:00
Shaun Arman
a42745b791 fix: add user_id support and OAuth shell permission (v0.2.6)
Some checks failed
Release / build-linux-arm64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Release / build-macos-arm64 (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
Fixes:
- Added shell:allow-open permission to fix OAuth integration flows
- Added user_id field to ProviderConfig for Custom REST provider CORE ID
- Added UI field for user_id when api_format is custom_rest
- Made userId optional in Custom REST provider requests (only sent if provided)
- Added X-msi-genai-client header to Custom REST provider requests
- Updated CSP to include Custom REST provider domains
- Bumped version to 0.2.6

This fixes:
- OAuth error: 'Command plugin:shell|open not allowed by ACL'
- Missing User ID field in Custom REST provider configuration UI
2026-04-03 16:34:00 -05:00
Shaun Arman
dd06566375 docs: add Custom REST provider documentation
Some checks failed
Release / build-macos-arm64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Release / build-linux-arm64 (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
- Added GenAI API User Guide.md with complete API specification
- Added HANDOFF-MSI-GENAI.md documenting custom provider implementation
- Includes API endpoints, request/response formats, available models, and rate limits
2026-04-03 15:45:52 -05:00
Shaun Arman
190084888c feat: add Custom REST provider support
- Extended ProviderConfig with optional custom fields for non-OpenAI APIs
- Added custom_endpoint_path, custom_auth_header, custom_auth_prefix fields
- Added api_format field to distinguish between OpenAI and Custom REST provider formats
- Added session_id field for stateful conversation APIs
- Implemented chat_custom_rest() method in OpenAI provider
- Custom REST provider uses different request format (prompt+sessionId) and response (msg field)
- Updated TypeScript types to match Rust schema
- Added UI controls in Settings/AIProviders for custom provider configuration
- API format selector auto-populates appropriate defaults (OpenAI vs Custom REST provider)
- Backward compatible: existing providers default to OpenAI format
2026-04-03 15:45:42 -05:00
Shaun Arman
4172616c8b feat: implement Confluence, ServiceNow, and Azure DevOps REST API clients
- Confluence: OAuth2 bearer auth, list_spaces, search_pages, publish_page, update_page
- ServiceNow: Basic auth, search_incidents, create_incident, get_incident, update_incident
- Azure DevOps: OAuth2 bearer auth, search_work_items, create_work_item, get_work_item, update_work_item
- Added TicketResult.id field to support both sys_id and ticket_number
- All implementations follow TDD with mockito HTTP mocking
- 19 tests passing across all three integrations
2026-04-03 15:43:37 -05:00
Shaun Arman
1e8ef41e64 feat: add OAuth2 frontend UI and complete integration flow
Some checks failed
Auto Tag / auto-tag (push) Successful in 4s
Test / rust-fmt-check (push) Successful in 2m5s
Release / build-macos-arm64 (push) Successful in 10m29s
Test / rust-clippy (push) Failing after 18m4s
Release / build-linux-arm64 (push) Failing after 22m1s
Test / rust-tests (push) Successful in 12m44s
Test / frontend-typecheck (push) Successful in 1m29s
Test / frontend-tests (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Phase 2.2: OAuth2 flow - FRONTEND COMPLETE 

Implemented:
- TypeScript command wrappers in tauriCommands.ts
  * initiateOauthCmd(service) -> OAuthInitResponse
  * handleOauthCallbackCmd(service, code, stateKey)
  * test*ConnectionCmd() for all services
  * OAuthInitResponse and ConnectionResult types

- Complete Settings/Integrations UI
  * Three integration cards: Confluence, ServiceNow, ADO
  * Connect with OAuth2 buttons (Confluence, ADO)
  * Basic auth note for ServiceNow
  * Configuration inputs: baseUrl, username, projectName, spaceKey
  * Test connection buttons with loading states
  * Success/error feedback with color-coded messages
  * OAuth2 flow instructions for users

- OAuth2 flow in browser
  * Opens auth URL in default browser via shell plugin
  * User authenticates with service
  * Redirected to localhost:8765/callback
  * Callback server handles token exchange automatically
  * Success message shown to user

- CSP updates in tauri.conf.json
  * Added http://localhost:8765 (callback server)
  * Added https://auth.atlassian.com (Confluence OAuth)
  * Added https://*.atlassian.net (Confluence API)
  * Added https://login.microsoftonline.com (ADO OAuth)
  * Added https://dev.azure.com (ADO API)

- UI improvements
  * Fixed Cancel button variant (ghost instead of secondary)
  * Loading spinners with Loader2 icon
  * Check/X icons for success/error states
  * Disabled states when not configured
  * Optimistic UI updates on connect

Frontend + Backend = COMPLETE END-TO-END OAUTH2 FLOW:
1. User goes to Settings → Integrations
2. Enters base URL and config
3. Clicks 'Connect with OAuth2'
4. Browser opens with service auth page
5. User logs in and authorizes
6. Redirected to localhost:8765/callback
7. Token exchanged and encrypted automatically
8. Stored in SQLite credentials table
9. Ready for API calls to external services 

TypeScript: All types checked, no errors
Frontend build:  Built in 2.26s
Total lines: ~400 lines of new UI code

Next: Phase 2.3 - Integration API clients (Confluence REST, ServiceNow REST, ADO REST)
2026-04-03 15:04:12 -05:00
Shaun Arman
05f4b51370 feat: implement OAuth2 callback server with automatic token exchange
Some checks are pending
Auto Tag / auto-tag (push) Waiting to run
Test / rust-fmt-check (push) Waiting to run
Test / rust-clippy (push) Waiting to run
Test / rust-tests (push) Waiting to run
Test / frontend-typecheck (push) Waiting to run
Test / frontend-tests (push) Waiting to run
Phase 2.2: OAuth2 flow - Part 3 (Callback server) COMPLETE 

Implemented:
- Local HTTP server on localhost:8765 using warp
  * GET /callback?code=...&state=... - OAuth redirect handler
  * GET /health - Health check endpoint
  * Graceful shutdown with oneshot channel

- Automatic callback handling
  * Server auto-starts on first initiate_oauth call
  * Background task listens for OAuth redirects
  * Automatically exchanges code for token
  * Stores encrypted token in database
  * Logs audit event for each successful OAuth

- Updated initiate_oauth command
  * Starts callback server if not running
  * Stores (service, verifier) tuple in OAuth state
  * Returns auth URL to open in browser/webview

- Updated handle_oauth_callback_internal
  * Accepts AppState reference (not State)
  * Called automatically by callback server
  * Exchanges code, encrypts token, stores in DB

- Beautiful success/error HTML pages
  * Green checkmark on success
  * Auto-closes window after 3 seconds
  * Clear error messages on failure

- Global state management
  * OAUTH_STATE: Maps state key -> (service, verifier)
  * CALLBACK_SERVER_SHUTDOWN: Holds shutdown channel
  * Thread-safe with Mutex wrappers

Dependencies added:
- warp 0.3 - Lightweight HTTP framework

TDD tests (7 passing with --test-threads=1):
Callback server tests:
  * Health endpoint verification
  * Callback parameter parsing
  * Missing/partial parameter handling
  * Graceful shutdown

Integration command tests:
  * OAuth state storage and retrieval
  * Multiple key management
  * OAuthInitResponse serialization

COMPLETE OAUTH2 FLOW:
1. User calls initiate_oauth("confluence")
2. Callback server starts (if not running)
3. Frontend receives auth URL
4. User opens URL in browser/webview
5. User authorizes, redirected to localhost:8765/callback?code=...
6. Callback server receives redirect
7. Token exchanged automatically
8. Token encrypted and stored in DB
9. Success page shown to user
10. Window auto-closes

Next: Frontend components (AuthWindow, Settings UI, CSP updates)
2026-04-03 14:59:39 -05:00
Shaun Arman
75302a1cc7 feat: add OAuth2 Tauri commands for integration authentication
Some checks are pending
Auto Tag / auto-tag (push) Waiting to run
Test / rust-fmt-check (push) Waiting to run
Test / rust-clippy (push) Waiting to run
Test / rust-tests (push) Waiting to run
Test / frontend-typecheck (push) Waiting to run
Test / frontend-tests (push) Waiting to run
Phase 2.2: OAuth2 flow - Part 2 (Tauri commands)

Implemented:
- initiate_oauth command
  * Generates PKCE challenge
  * Creates state key for OAuth session
  * Stores verifier in global OAuth state
  * Returns authorization URL for Confluence/ADO
  * ServiceNow uses basic auth (not OAuth2)

- handle_oauth_callback command
  * Retrieves and removes verifier from state
  * Exchanges authorization code for access token
  * Encrypts and stores token in DB
  * Logs audit event for successful OAuth

- OAuthInitResponse type for frontend
  * auth_url: Full OAuth authorization URL
  * state: Session key for callback matching

- Global OAUTH_STATE storage (lazy_static)
  * Thread-safe HashMap for PKCE verifiers
  * Temporary storage during OAuth flow
  * Automatically cleaned up after exchange

Service configuration:
- Confluence: auth.atlassian.com OAuth2
- Azure DevOps: login.microsoftonline.com OAuth2
- ServiceNow: Basic auth (not OAuth2)

Client IDs from env vars:
- CONFLUENCE_CLIENT_ID
- ADO_CLIENT_ID

Dependencies added:
- lazy_static 1.4 - Global static initialization

TDD tests (3 passing):
- OAuth state storage and retrieval
- Multiple key management
- OAuthInitResponse serialization

Commands registered in lib.rs generate_handler![]

Next: Local HTTP callback server for OAuth redirects
2026-04-03 14:50:13 -05:00
Shaun Arman
01474fb5f2 feat: implement OAuth2 token exchange and AES-256-GCM encryption
Phase 2.2: OAuth2 flow - Part 1 (Token exchange + encryption)

Implemented:
- OAuth2 authorization code exchange with PKCE
  * Real HTTP POST to token endpoint
  * Parses access_token, refresh_token, expires_in, token_type
  * Calculates expires_at timestamp

- AES-256-GCM token encryption
  * Uses TFTSR_ENCRYPTION_KEY env var (or dev default)
  * Random nonce per encryption (12 bytes)
  * Base64-encoded output with nonce prepended
  * Proper key derivation (32 bytes)

- Updated credential storage
  * store_pat() now encrypts tokens before DB storage
  * get_pat() decrypts tokens on retrieval
  * Stores both token_hash (audit) and encrypted_token (actual)

Dependencies added:
- mockito 1.7.2 (dev) - HTTP mocking for tests
- aes-gcm 0.10 - AES-256-GCM encryption
- rand 0.8 - Cryptographically secure RNG

TDD tests (20 passing with --test-threads=1):
- OAuth exchange: success, missing token, HTTP error, network error
- Encryption: roundtrip, different nonces, invalid data, wrong key
- PAT storage: store/retrieve, nonexistent service, replacement

Note: Tests require single-threaded execution due to env var
test isolation. This is acceptable for CI/CD.
2026-04-03 14:32:17 -05:00
Shaun Arman
fd244781e1 feat: add database schema for integration credentials and config
Some checks failed
Test / frontend-typecheck (push) Waiting to run
Test / frontend-tests (push) Waiting to run
Auto Tag / auto-tag (push) Successful in 6s
Release / build-macos-arm64 (push) Failing after 1m32s
Test / rust-fmt-check (push) Successful in 2m6s
Test / rust-clippy (push) Successful in 17m38s
Release / build-linux-arm64 (push) Failing after 20m53s
Test / rust-tests (push) Has been cancelled
Release / build-linux-amd64 (push) Failing after 13m24s
Release / build-windows-amd64 (push) Failing after 7m37s
Phase 2.1: Database schema + credentials storage

Added migration 011 with:
- credentials table: Encrypted OAuth tokens per service
- integration_config table: Base URLs, project names, space keys

Added models:
- Credential: Stores token hash and encrypted token
- IntegrationConfig: Stores service configuration

TDD tests (7 passing):
- Table creation verification
- Column structure validation
- Insert/retrieve operations
- Service uniqueness constraints
- Migration tracking
- Idempotency checks

All tests pass. Schema ready for OAuth2 implementation.
2026-04-03 14:23:49 -05:00
Shaun Arman
bbc43f7428 fix: improve Cancel button contrast in AI disclaimer modal
Changed variant from 'outline' to 'secondary' for better visibility
in dark theme. The outline variant had insufficient contrast making
the button difficult to read.
2026-04-03 14:20:44 -05:00
Shaun Arman
bc93f48711 chore: bump version to 0.2.2
Some checks failed
Test / frontend-tests (push) Waiting to run
Auto Tag / auto-tag (push) Successful in 4s
Test / rust-fmt-check (push) Successful in 2m11s
Release / build-macos-arm64 (push) Successful in 6m30s
Test / rust-clippy (push) Successful in 17m21s
Release / build-linux-arm64 (push) Failing after 21m36s
Test / rust-tests (push) Successful in 12m42s
Test / frontend-typecheck (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
2026-04-03 13:51:25 -05:00
Shaun Arman
b6b4b9f7f9 chore: bump version to 0.2.1
Some checks failed
Auto Tag / auto-tag (push) Has been cancelled
Test / rust-fmt-check (push) Has been cancelled
Test / rust-clippy (push) Has been cancelled
Test / rust-tests (push) Has been cancelled
Test / frontend-typecheck (push) Has been cancelled
Test / frontend-tests (push) Has been cancelled
2026-04-03 13:49:33 -05:00
Shaun Arman
60e4fe93a4 feat: add AI disclaimer modal before creating new issues
Some checks failed
Test / rust-fmt-check (push) Successful in 1m28s
Test / rust-clippy (push) Successful in 11m35s
Test / rust-tests (push) Successful in 12m33s
Test / frontend-typecheck (push) Successful in 1m37s
Test / frontend-tests (push) Successful in 1m40s
Auto Tag / auto-tag (push) Successful in 7s
Release / build-macos-arm64 (push) Successful in 6m16s
Release / build-windows-amd64 (push) Has been cancelled
Release / build-linux-arm64 (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Add professional disclaimer warning that users must accept before
creating issues. Modal appears on first visit to New Issue page.

Disclaimer covers:
- AI can make mistakes and hallucinate
- AI may provide incorrect or outdated information
- Commands may have unintended consequences
- User bears full responsibility for any actions taken
- Best practices for using AI recommendations safely

Features:
- Modal overlay with clear warning sections
- Color-coded sections (red for risks, yellow for responsibility)
- Scrollable content area for long disclaimer
- Acceptance stored in localStorage (persists across sessions)
- Re-shows modal if user tries to create issue without accepting
- Cancel button returns to dashboard

Tested: TypeScript compilation ✓, Rust formatting ✓

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-03 13:03:48 -05:00
Shaun Arman
945ff6c6a4 fix: implement native DOCX export without pandoc dependency
Some checks failed
Test / rust-tests (push) Waiting to run
Test / frontend-typecheck (push) Waiting to run
Test / frontend-tests (push) Waiting to run
Auto Tag / auto-tag (push) Failing after 4s
Test / rust-fmt-check (push) Successful in 1m32s
Test / rust-clippy (push) Has been cancelled
Replace pandoc-based DOCX export with native Rust implementation
using docx-rs crate. DOCX export now works out of the box without
requiring users to install external tools.

Changes:
- Added docx-rs dependency to Cargo.toml
- Implemented export_docx() in exporter.rs
- Removed pandoc subprocess calls from docs.rs
- Uses same markdown parsing as PDF export
- Handles titles, headings, and normal text with appropriate styling

Tested:
- Rust compilation ✓
- Rust formatting ✓
- TypeScript types ✓

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-03 12:53:36 -05:00
Shaun Arman
f738ee26ed chore: bump version to 0.2.0 after cleanup
Some checks failed
Auto Tag / auto-tag (push) Successful in 4s
Test / rust-fmt-check (push) Successful in 2m11s
Release / build-macos-arm64 (push) Successful in 5m40s
Test / rust-tests (push) Has been cancelled
Test / frontend-typecheck (push) Has been cancelled
Test / frontend-tests (push) Has been cancelled
Test / rust-clippy (push) Has been cancelled
Release / build-linux-amd64 (push) Has been cancelled
Release / build-windows-amd64 (push) Has been cancelled
Release / build-linux-arm64 (push) Has been cancelled
Fresh start with clean release history.

All previous tags and releases have been cleaned up.
This commit will trigger auto-tag to create v0.2.0.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-03 12:39:43 -05:00
Shaun Arman
6602fd7cd2 fix: improve download button visibility and add DOCX export
Some checks failed
Test / rust-fmt-check (push) Has been cancelled
Test / rust-clippy (push) Has been cancelled
Test / rust-tests (push) Has been cancelled
Test / frontend-typecheck (push) Has been cancelled
Test / frontend-tests (push) Has been cancelled
Auto Tag / auto-tag (push) Has been cancelled
1. Download Button Visibility:
   - Changed from variant=outline to default variant (solid background)
   - Provides better contrast and icon visibility in both themes
   - Removed unnecessary text-foreground class

2. DOCX Export Support:
   - Added DOCX export via pandoc conversion
   - Writes temp markdown file, converts with pandoc, cleans up
   - Returns clear error if pandoc not installed
   - Supports same workflow as MD/PDF exports

3. Triaging Status Investigation:
   - triaging status is defined in schema and used in dashboard counts
   - Currently not automatically set when entering triage
   - Kept in filter dropdown as part of the data model

Tested: Rust compilation, TypeScript types, Rust formatting

Note: DOCX export requires pandoc to be installed on the system.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-04-03 12:33:27 -05:00