Skip to content

Conversation

@d-klotz
Copy link
Contributor

@d-klotz d-klotz commented Dec 23, 2025

Summary

Adds frigg auth command for testing API module authentication flows without deploying full Frigg infrastructure. This enables API module developers to quickly validate OAuth2 and API-Key authentication during development.

Demo

🎥 Watch the demo

Features

  • OAuth2 authentication with local callback server (auto-opens browser)
  • API-Key authentication with interactive JSON Schema forms
  • Credential persistence to .frigg-credentials.json (auto-added to .gitignore)
  • Comprehensive testing of all requiredAuthMethods:
    • testAuthRequest - Verify authentication works
    • getEntityDetails - Validate entity consistency post-auth
    • getCredentialDetails - Verify credential structure
    • Token refresh (if module supports it)
    • apiPropertiesToPersist verification (credential + entity properties)

Interactive JSON Schema Forms for API-Key Modules

API-Key modules with getAuthorizationRequirements render interactive CLI forms:

$ frigg auth test .

📝 Quo API Authorization

  (Your Quo API key)
  API Key: ********************************

🔑 API-Key Authentication Flow

Module: quo
✓ API key configured

Form features:

  • Displays title from jsonSchema.title
  • Shows help text from ui:help before each field
  • Masks password fields (ui:widget: 'password') with *
  • Validates required fields
  • Multi-field support (e.g., company ID, public key, private key)

The --api-key flag still works and bypasses the form.

Commands

# Test OAuth2 authentication
frigg auth test .              # Current directory module
frigg auth test attio          # By module name
frigg auth test . --port 8080  # Custom callback port

# Test API-Key authentication (interactive form)
frigg auth test .              # Renders JSON Schema form if getAuthorizationRequirements exists

# Test API-Key authentication (explicit)
frigg auth test . --api-key sk_xxx

# Manage saved credentials
frigg auth list                # List all saved credentials
frigg auth get attio --json    # Get as JSON for scripts
frigg auth delete attio        # Delete credentials

Test Plan

  • OAuth2 flow tested with Attio module
  • API-Key flow tested with Quo module (interactive form)
  • Credentials saved and retrievable
  • All requiredAuthMethods validated post-auth
  • Summary output shows pass/skip/fail for each test

Add `frigg auth` command for testing API module authentication flows
without deploying full Frigg infrastructure.

Features:
- OAuth2 authentication with local callback server
- API-Key authentication support
- Credential persistence to .frigg-credentials.json
- Comprehensive testing of all requiredAuthMethods

Commands:
- `frigg auth test <module>` - Test authentication flow
- `frigg auth list` - List saved credentials
- `frigg auth get <module>` - Retrieve credentials
- `frigg auth delete [module]` - Remove credentials
API-Key modules with `getAuthorizationRequirements` now render an interactive
CLI form instead of requiring the `--api-key` flag. The form:

- Displays title from jsonSchema.title
- Shows help text from ui:help before each field
- Masks password fields (ui:widget: 'password') with *
- Validates required fields
- Supports multi-field forms (e.g., company ID, public key, private key)

The `--api-key` flag still works and takes precedence over the form.

Files added:
- json-schema-form.js - Renders JSON Schema as CLI prompts using @inquirer/prompts

Files modified:
- api-key-flow.js - Calls getAuthorizationRequirements when no --api-key provided
- index.js - Removed hard requirement for --api-key flag
- README.md, CLAUDE.md, SKILL.md - Documentation updates
- Remove sample API call step (testAuthRequest is authoritative)
- Fix credentials saved under CLI arg instead of actual module name
- Remove --no-browser option (always open browser for OAuth)
Comment on lines +24 to +35
// Extract API key from form data - try common field names
apiKey = formData.apiKey || formData.api_key ||
formData.access_token || formData.token;

// If still no API key found, use the first value from the form
if (!apiKey && Object.keys(formData).length > 0) {
apiKey = Object.values(formData)[0];
}

if (!apiKey) {
throw new Error('No API key provided in form');
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Critical bug: Multi-field authentication forms lose data. The code extracts only a single field as apiKey from formData, discarding all other fields. For modules like ConnectWise (documented in README) that require multiple fields (companyId, publicKey, privateKey, siteUrl), only one field will be extracted and the rest will be lost.

When setAuthParams is called later (lines 61-66), it only receives the single extracted apiKey value, not the complete formData object. This breaks multi-field authentication flows.

Fix: Pass the entire formData object to setAuthParams instead of extracting a single field:

if (!apiKey) {
    if (definition.requiredAuthMethods?.getAuthorizationRequirements) {
        const tempApi = new ApiClass({ ...definition.env });
        const authReqs = definition.requiredAuthMethods.getAuthorizationRequirements(tempApi);

        if (authReqs?.data?.jsonSchema) {
            formData = await renderJsonSchemaForm(
                authReqs.data.jsonSchema,
                authReqs.data.uiSchema
            );
            
            // For backwards compatibility, try to extract a single API key
            apiKey = formData.apiKey || formData.api_key || 
                     formData.access_token || formData.token;
        }
    }
    // ...
}

// Later at line 61-66, pass formData:
if (definition.requiredAuthMethods?.setAuthParams) {
    await definition.requiredAuthMethods.setAuthParams(api, formData || {
        apiKey,
        data: { apiKey, api_key: apiKey, access_token: apiKey }
    });
    apiKeySet = true;
}

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants