Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Test authenticated routes in the your project using cookie-based authentication. Use this skill when testing API endpoints, validating route functionality, or debugging authentication issues. Includes patterns for using test-auth-route.js and mock authentication.
.claude/skills/microck-route-tester/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 92% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 76% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 155% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 68% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 100% | 0% |
This skill provides patterns for testing authenticated routes in the your project using cookie-based JWT authentication.
The your project uses:
refresh_tokenconfig.iniThe test-auth-route.js script handles all authentication complexity automatically.
Location: /root/git/your project_pre/scripts/test-auth-route.js
bashnode scripts/test-auth-route.js http://localhost:3000/blog-api/api/endpoint
bashnode scripts/test-auth-route.js \ http://localhost:3000/blog-api/777/submit \ POST \ '{"responses":{"4577":"13295"},"submissionID":5,"stepInstanceId":"11"}'
testusertestpasswordconfig.inirefresh_token=<signed-token>The script outputs:
Note: The script is verbose - look for the actual response in the output.
Use the curl command from the test-auth-route.js output:
bash# The script outputs something like: # 💡 To test manually with curl: # curl -b "refresh_token=eyJhbGci..." http://localhost:3000/blog-api/api/endpoint # Copy and modify that curl command: curl -X POST http://localhost:3000/blog-api/777/submit \ -H "Content-Type: application/json" \ -b "refresh_token=<COPY_TOKEN_FROM_SCRIPT_OUTPUT>" \ -d '{"your": "data"}'
For development, bypass Keycloak entirely using mock auth.
bash# Add to service .env file (e.g., blog-api/.env) MOCK_AUTH=true MOCK_USER_ID=test-user MOCK_USER_ROLES=admin,operations
bashcurl -H "X-Mock-Auth: true" \ -H "X-Mock-User: test-user" \ -H "X-Mock-Roles: admin,operations" \ http://localhost:3002/api/protected
Mock auth ONLY works when:
NODE_ENV is development or testmockAuth middleware is added to the routebashnode scripts/test-auth-route.js \ http://localhost:3000/blog-api/777/submit \ POST \ '{"responses":{"4577":"13295"},"submissionID":5,"stepInstanceId":"11"}'
bashnode scripts/test-auth-route.js \ http://localhost:3002/api/workflow/start \ POST \ '{"workflowCode":"DHS_CLOSEOUT","entityType":"Submission","entityID":123}'
bashnode scripts/test-auth-route.js \ http://localhost:3002/api/workflow/step/complete \ POST \ '{"stepInstanceID":789,"answers":{"decision":"approved","comments":"Looks good"}}'
bashnode scripts/test-auth-route.js \ "http://localhost:3002/api/workflows?status=active&limit=10"
bash# Get token from test-auth-route.js first, then: curl -X POST http://localhost:5000/upload \ -H "Content-Type: multipart/form-data" \ -b "refresh_token=<TOKEN>" \ -F "file=@/path/to/file.pdf" \ -F "metadata={\"description\":\"Test file\"}"
The test-auth-route.js script uses these credentials:
testusertestpasswordconfig.ini (usually http://localhost:8081)yourRealmconfig.ini| Service | Port | Base URL | |---------|------|----------| | Users | 3000 | http://localhost:3000 | | Projects| 3001 | http://localhost:3001 | | Form | 3002 | http://localhost:3002 | | Email | 3003 | http://localhost:3003 | | Uploads | 5000 | http://localhost:5000 |
Check /src/app.ts in each service for route prefixes:
typescript// Example from blog-api/src/app.ts app.use('/blog-api/api', formRoutes); // Prefix: /blog-api/api app.use('/api/workflow', workflowRoutes); // Prefix: /api/workflow
Full Route = Base URL + Prefix + Route Path
Example:
http://localhost:3002/form/777/submithttp://localhost:3000/blog-api/777/submitBefore testing a route:
app.tsAfter testing routes that modify data:
bash# Connect to MySQL docker exec -i local-mysql mysql -u root -ppassword1 blog_dev # Check specific table mysql> SELECT * FROM WorkflowInstance WHERE id = 123; mysql> SELECT * FROM WorkflowStepInstance WHERE instanceId = 123; mysql> SELECT * FROM WorkflowNotification WHERE recipientUserId = 'user-123';
Possible causes:
Solutions:
bash# Check Keycloak is running docker ps | grep keycloak # Regenerate token node scripts/test-auth-route.js http://localhost:3002/api/health # Verify config.ini has correct jwtSecret
Possible causes:
Solutions:
bash# Use mock auth with admin role curl -H "X-Mock-Auth: true" \ -H "X-Mock-User: test-admin" \ -H "X-Mock-Roles: admin" \ http://localhost:3002/api/protected
Possible causes:
Solutions:
app.ts for route prefixespm2 list)Possible causes:
Solutions:
pm2 logs <service>)For comprehensive route testing after making changes:
The agent will:
bash# 1. Test with valid data node scripts/test-auth-route.js \ http://localhost:3002/api/my-new-route \ POST \ '{"field1":"value1","field2":"value2"}' # 2. Verify database docker exec -i local-mysql mysql -u root -ppassword1 blog_dev \ -e "SELECT * FROM MyTable ORDER BY createdAt DESC LIMIT 1;" # 3. Test with invalid data node scripts/test-auth-route.js \ http://localhost:3002/api/my-new-route \ POST \ '{"field1":"invalid"}' # 4. Test without authentication curl http://localhost:3002/api/my-new-route # Should return 401
bash# 1. Test existing functionality still works node scripts/test-auth-route.js \ http://localhost:3002/api/existing-route \ POST \ '{"existing":"data"}' # 2. Test new functionality node scripts/test-auth-route.js \ http://localhost:3002/api/existing-route \ POST \ '{"new":"field","existing":"data"}' # 3. Verify backward compatibility # Test with old request format (if applicable)
ini[keycloak] url = http://localhost:8081 realm = yourRealm clientId = app-client [jwt] jwtSecret = your-jwt-secret-here
bashNODE_ENV=development MOCK_AUTH=true # Optional: Enable mock auth MOCK_USER_ID=test-user # Optional: Default mock user MOCK_USER_ROLES=admin # Optional: Default mock roles
/root/git/your project_pre/scripts/test-auth-route.js - Main testing script/blog-api/src/app.ts - Form service routes/notifications/src/app.ts - Email service routes/auth/src/app.ts - Users service routes/config.ini - Service configuration/.env - Environment variables| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 12,666 | 7,489 | -41% | 1 | 1 | 0% | 2,252 | 4,325 | +92% | 0 | 0 | — |
case-02 | fail→pass | 15,990 | 11,061 | -31% | 1 | 1 | 0% | 2,782 | 4,893 | +76% | 0 | 0 | — |
case-03 | fail→pass | 8,937 | 7,274 | -19% | 1 | 1 | 0% | 1,665 | 4,245 | +155% | 0 | 0 | — |
case-04 | fail→pass | 13,142 | 4,779 | -64% | 1 | 1 | 0% | 2,229 | 3,748 | +68% | 0 | 0 | — |
case-05 | fail→pass | 10,839 | 3,897 | -64% | 1 | 1 | 0% | 1,802 | 3,607 | +100% | 0 | 0 | — |
case-06 | fail→pass | 8,656 | 3,384 | -61% | 1 | 1 | 0% | 1,408 | 3,472 | +147% | 0 | 0 | — |
case-07 | fail→pass | 7,079 | 4,144 | -41% | 1 | 1 | 0% | 1,235 | 3,625 | +194% | 0 | 0 | — |
case-08 | fail→pass | 9,221 | 3,417 | -63% | 1 | 1 | 0% | 1,780 | 3,507 | +97% | 0 | 0 | — |
case-09 | fail→pass | 8,598 | 3,270 | -62% | 1 | 1 | 0% | 1,564 | 3,524 | +125% | 0 | 0 | — |
case-10 | fail→pass | 9,991 | 2,615 | -74% | 1 | 1 | 0% | 1,692 | 3,338 | +97% | 0 | 0 | — |
case-11 | fail→fail | 11,166 | 1,628 | -85% | 1 | 1 | 0% | 1,928 | 3,054 | +58% | 0 | 0 | — |
case-12 | fail→fail | 10,474 | 3,090 | -70% | 1 | 1 | 0% | 1,737 | 3,345 | +93% | 0 | 0 | — |
case-13 | fail→fail | 2,391 | 3,026 | +27% | 1 | 1 | 0% | 431 | 3,291 | +664% | 0 | 0 | — |
case-14 | fail→fail | 11,385 | 4,423 | -61% | 1 | 1 | 0% | 1,987 | 3,638 | +83% | 0 | 0 | — |
case-15 | fail→fail | 9,222 | 2,792 | -70% | 1 | 1 | 0% | 1,538 | 3,342 | +117% | 0 | 0 | — |
case-16 | fail→fail | 6,517 | 2,920 | -55% | 1 | 1 | 0% | 1,206 | 3,297 | +173% | 0 | 0 | — |
case-17 | fail→pass | 7,433 | 2,696 | -64% | 1 | 1 | 0% | 1,211 | 3,338 | +176% | 0 | 0 | — |
case-18 | fail→fail | 10,127 | 1,808 | -82% | 1 | 1 | 0% | 1,729 | 3,144 | +82% | 0 | 0 | — |
case-19 | fail→pass | 7,673 | 5,352 | -30% | 1 | 1 | 0% | 1,315 | 3,801 | +189% | 0 | 0 | — |
case-20 | pass→fail | 11,914 | 9,023 | -24% | 1 | 1 | 0% | 2,084 | 4,437 | +113% | 0 | 0 | — |
case-21 | pass→pass | 27,011 | 12,142 | -55% | 1 | 1 | 0% | 3,231 | 5,166 | +60% | 0 | 0 | — |
case-22 | pass→pass | 8,625 | 6,755 | -22% | 1 | 1 | 0% | 1,700 | 4,113 | +142% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +50 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.