@friggframework/devtools 2.0.0-next.64 → 2.0.0-next.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,293 @@
1
+ # CLAUDE.md - Frigg Authenticator
2
+
3
+ This file provides guidance to Claude Code when working with the Frigg Authenticator tool.
4
+
5
+ ## Overview
6
+
7
+ The Frigg Authenticator is a CLI tool for testing API module authentication flows. It's part of `@friggframework/devtools` and enables developers to validate OAuth2 and API-Key authentication without deploying full Frigg infrastructure.
8
+
9
+ ## Directory Structure
10
+
11
+ ```
12
+ auth-command/
13
+ ├── index.js # Main CLI command handler (test, list, get, delete)
14
+ ├── module-loader.js # Dynamic module loading & validation
15
+ ├── credential-storage.js # .frigg-credentials.json persistence
16
+ ├── oauth-callback-server.js # Local HTTP server for OAuth callbacks
17
+ ├── oauth-flow.js # OAuth2 flow orchestration
18
+ ├── api-key-flow.js # API-Key authentication flow
19
+ ├── json-schema-form.js # Interactive JSON Schema form renderer (CLI prompts)
20
+ ├── auth-tester.js # Run testAuthRequest & sample API calls
21
+ ├── utils/
22
+ │ └── browser.js # Cross-platform browser opening
23
+ ├── README.md # User documentation
24
+ └── CLAUDE.md # This file - AI assistant guidance
25
+ ```
26
+
27
+ ## Key Files and Their Purpose
28
+
29
+ ### `index.js` - Command Handler
30
+ Main entry point that exports `authCommand` object with methods:
31
+ - `test(moduleName, options)` - Test authentication for a module
32
+ - `list(options)` - List saved credentials
33
+ - `get(moduleName, options)` - Retrieve credentials
34
+ - `delete(moduleName, options)` - Remove credentials
35
+
36
+ **When to modify:** Adding new subcommands or changing command behavior.
37
+
38
+ ### `module-loader.js` - Module Loading
39
+ Handles dynamic loading of API modules from various sources:
40
+ - Current directory (`.`)
41
+ - Relative/absolute paths (`./path/to/module`)
42
+ - Short names (`attio` → `@friggframework/api-module-attio`)
43
+ - Full package names (`@friggframework/api-module-attio`)
44
+
45
+ **Key functions:**
46
+ - `loadModule(moduleIdentifier)` - Load and return `{definition, Api, modulePath}`
47
+ - `validateModule(definition)` - Ensure module has required fields
48
+ - `getAuthType(Api)` - Detect auth type (oauth2 or apiKey)
49
+
50
+ **When to modify:** Supporting new module locations or validation rules.
51
+
52
+ ### `credential-storage.js` - Persistence
53
+ Manages `.frigg-credentials.json` file:
54
+ - Stores credentials per module
55
+ - Supports global (`~/.frigg-credentials.json`) and local storage
56
+ - Auto-adds to `.gitignore`
57
+
58
+ **Key class:** `CredentialStorage`
59
+ - `save(moduleName, credentials, authType)`
60
+ - `get(moduleName)`
61
+ - `list()`
62
+ - `delete(moduleName)`
63
+ - `deleteAll()`
64
+
65
+ **When to modify:** Changing storage format or location logic.
66
+
67
+ ### `oauth-callback-server.js` - OAuth Server
68
+ Local HTTP server that captures OAuth callbacks:
69
+ - Listens on configurable port (default: 3333)
70
+ - Handles `?code=` and `?error=` query params
71
+ - Returns success/error HTML pages
72
+ - Implements timeout handling
73
+
74
+ **Key class:** `OAuthCallbackServer`
75
+ - `start()` - Start the server
76
+ - `waitForCode()` - Promise that resolves with `{code, state}`
77
+ - `stop()` - Shutdown the server
78
+
79
+ **When to modify:** Changing callback behavior or HTML responses.
80
+
81
+ ### `oauth-flow.js` - OAuth2 Orchestration
82
+ Orchestrates the complete OAuth2 flow:
83
+ 1. Generate CSRF state token
84
+ 2. Create API instance with env params
85
+ 3. Get authorization URL
86
+ 4. Start callback server
87
+ 5. Open browser or print URL
88
+ 6. Wait for callback
89
+ 7. Verify state (CSRF protection)
90
+ 8. Exchange code for tokens via `getToken()`
91
+ 9. Fetch entity details via `getEntityDetails()`
92
+ 10. Return credentials object
93
+
94
+ **Key function:** `runOAuthFlow(definition, ApiClass, options)`
95
+
96
+ **When to modify:** Changing OAuth flow steps or adding features.
97
+
98
+ ### `api-key-flow.js` - API-Key Flow
99
+ Handles API-Key authentication:
100
+ 1. Check for `getAuthorizationRequirements` in module definition
101
+ 2. If no API key provided and `getAuthorizationRequirements` exists, render JSON Schema form
102
+ 3. Create API instance
103
+ 4. Set API key via `setApiKey()` or similar
104
+ 5. Fetch entity details
105
+ 6. Return credentials object
106
+
107
+ **Key function:** `runApiKeyFlow(definition, ApiClass, apiKey, options)`
108
+
109
+ **When to modify:** Supporting different API key mechanisms or form rendering.
110
+
111
+ ### `json-schema-form.js` - Interactive Form Renderer
112
+ Renders JSON Schema as interactive CLI prompts using `@inquirer/prompts`:
113
+ 1. Display form title from `jsonSchema.title`
114
+ 2. Iterate through `jsonSchema.properties`
115
+ 3. Show help text from `uiSchema[field]['ui:help']`
116
+ 4. Use password prompt for `ui:widget: 'password'` fields
117
+ 5. Validate required fields
118
+ 6. Return collected form data
119
+
120
+ **Key function:** `renderJsonSchemaForm(jsonSchema, uiSchema)`
121
+
122
+ **When to modify:** Adding new field types or UI schema options.
123
+
124
+ **Example output:**
125
+ ```
126
+ 📝 Quo API Authorization
127
+
128
+ (Your Quo API key)
129
+ API Key: ********************************
130
+ ```
131
+
132
+ ### `auth-tester.js` - Verification
133
+ Runs verification tests after authentication:
134
+ 1. Create fresh API instance with credentials
135
+ 2. Run `testAuthRequest` from module definition
136
+ 3. Try common sample API methods
137
+ 4. Verify credential properties are set
138
+
139
+ **Key function:** `runAuthTests(definition, ApiClass, credentials, options)`
140
+
141
+ **When to modify:** Adding verification steps or sample methods.
142
+
143
+ ### `utils/browser.js` - Browser Opening
144
+ Cross-platform browser opening utility:
145
+ - macOS: `open`
146
+ - Windows: `start`
147
+ - Linux: `xdg-open`
148
+
149
+ **Key function:** `openBrowser(url)`
150
+
151
+ ## Integration with Frigg CLI
152
+
153
+ The authenticator is registered in `frigg-cli/index.js`:
154
+
155
+ ```javascript
156
+ const { authCommand } = require('./auth-command');
157
+
158
+ const authProgram = program
159
+ .command('auth')
160
+ .description('Test API module authentication');
161
+
162
+ authProgram
163
+ .command('test <module>')
164
+ .action(authCommand.test);
165
+ // ... more subcommands
166
+ ```
167
+
168
+ ## Common Development Tasks
169
+
170
+ ### Adding a New Subcommand
171
+
172
+ 1. Add handler method in `auth-command/index.js`
173
+ 2. Register in `frigg-cli/index.js` under `authProgram`
174
+ 3. Update README.md with usage docs
175
+
176
+ ### Supporting a New Auth Type
177
+
178
+ 1. Create new flow file (e.g., `basic-auth-flow.js`)
179
+ 2. Update `getAuthType()` in `module-loader.js`
180
+ 3. Add case in `test()` handler in `index.js`
181
+
182
+ ### Changing Credential Format
183
+
184
+ 1. Update `save()` and `get()` in `credential-storage.js`
185
+ 2. Consider migration for existing credentials
186
+ 3. Update `_meta.version` for format versioning
187
+
188
+ ### Adding Verification Steps
189
+
190
+ 1. Modify `runAuthTests()` in `auth-tester.js`
191
+ 2. Add new sample methods to check
192
+ 3. Update verbose output
193
+
194
+ ## Testing
195
+
196
+ ### Manual Testing
197
+
198
+ ```bash
199
+ # Test with a real module
200
+ cd /path/to/api-module-attio
201
+ export ATTIO_CLIENT_ID=xxx
202
+ export ATTIO_CLIENT_SECRET=xxx
203
+ export ATTIO_SCOPE="read:objects"
204
+ export REDIRECT_URI="http://localhost:3333"
205
+ node /path/to/frigg-cli/index.js auth test . --verbose
206
+ ```
207
+
208
+ ### Unit Testing
209
+
210
+ Tests should be added to `frigg-cli/test/auth-command.test.js`:
211
+ - Test module loading with various paths
212
+ - Test credential storage operations
213
+ - Mock OAuth callback server responses
214
+ - Test error handling
215
+
216
+ ## Error Handling Patterns
217
+
218
+ ### User-Friendly Errors
219
+
220
+ ```javascript
221
+ throw new Error(
222
+ `Port ${port} is already in use.\n` +
223
+ `Try using a different port: frigg auth test <module> --port <different-port>`
224
+ );
225
+ ```
226
+
227
+ ### Validation Errors
228
+
229
+ ```javascript
230
+ const errors = [];
231
+ if (!definition.moduleName) {
232
+ errors.push('Missing required field: moduleName');
233
+ }
234
+ if (errors.length > 0) {
235
+ throw new Error(`Module validation failed:\n${errors.map(e => ` - ${e}`).join('\n')}`);
236
+ }
237
+ ```
238
+
239
+ ## Dependencies
240
+
241
+ External packages used:
242
+ - `chalk` - Terminal colors
243
+ - `commander` - CLI framework (via parent)
244
+ - `@inquirer/prompts` - Interactive CLI prompts (input, password)
245
+
246
+ Node.js built-ins:
247
+ - `http` - Callback server
248
+ - `url` - URL parsing
249
+ - `fs` - File system
250
+ - `path` - Path utilities
251
+ - `os` - OS info
252
+ - `crypto` - State token generation
253
+ - `child_process` - Browser opening
254
+ - `readline` - User confirmation
255
+
256
+ ## Security Considerations
257
+
258
+ 1. **State Parameter**: CSRF protection via random state token
259
+ 2. **Local Only**: Callback server only binds to localhost
260
+ 3. **No Credential Logging**: Sensitive values are masked in output
261
+ 4. **Gitignore Integration**: Auto-adds credentials file to .gitignore
262
+ 5. **Sanitization**: Client secrets removed from stored apiParams
263
+
264
+ ## Common Issues
265
+
266
+ ### Module Not Loading
267
+
268
+ Check:
269
+ - Module exports `{Definition}` or `{definition}`
270
+ - Definition has `API` class
271
+ - `require('dotenv').config()` is called in definition.js
272
+
273
+ ### OAuth Flow Failing
274
+
275
+ Check:
276
+ - Environment variables are set correctly
277
+ - Redirect URI matches callback server port
278
+ - OAuth credentials are valid
279
+ - Scopes are correct
280
+
281
+ ### Credentials Not Persisting
282
+
283
+ Check:
284
+ - Write permissions on target directory
285
+ - File isn't gitignored in a way that prevents reading
286
+ - Storage path detection is correct
287
+
288
+ ## Related Documentation
289
+
290
+ - [Frigg Framework CLAUDE.md](../../CLAUDE.md)
291
+ - [API Module Library](https://github.com/friggframework/api-module-library)
292
+ - [OAuth2Requester](../../../core/modules/requester/oauth-2.js)
293
+ - [ApiKeyRequester](../../../core/modules/requester/ApiKeyRequester.js)