Skip to content

feat: Add user query endpoints for existence check and passkey listing#3

Open
eminogrande wants to merge 1 commit into
mainfrom
docs/api-documentation
Open

feat: Add user query endpoints for existence check and passkey listing#3
eminogrande wants to merge 1 commit into
mainfrom
docs/api-documentation

Conversation

@eminogrande
Copy link
Copy Markdown
Contributor

@eminogrande eminogrande commented Aug 12, 2025

Summary

This PR adds two new API endpoints to enhance user management capabilities:

  • Check if a username exists in the system
  • List all passkeys registered for a specific user

New Endpoints

1. Check User Existence

  • Endpoint: GET /api/users/:username/exists
  • Purpose: Verify if a username is already registered
  • Response: { "exists": true/false }

2. List User Passkeys

  • Endpoint: GET /api/users/:username/passkeys
  • Purpose: Retrieve all registered passkeys for a user
  • Response: Array with credential details and device information

Changes Made

Code Changes

  • ✅ Added two new GET endpoints in index.js
  • ✅ Implemented intelligent device name detection based on WebAuthn transport types
  • ✅ Added proper error handling for non-existent users
  • ✅ Results sorted by most recently used passkey

Documentation

  • ✅ Created comprehensive API documentation in docs/API.md
  • ✅ Updated README.md with endpoint references
  • ✅ Added detailed request/response examples
  • ✅ Documented error scenarios and status codes

Testing

Production Testing (https://passkey.nuri.com)

# Check if user exists
curl "https://passkey.nuri.com/api/users/satoshi%40gmx.com/exists"
# Response: {"exists": true}

# List user passkeys
curl "https://passkey.nuri.com/api/users/satoshi%40gmx.com/passkeys"
# Response: {"passkeys": [...]}

# Non-existent user
curl "https://passkey.nuri.com/api/users/nonexistent%40test.com/exists"
# Response: {"exists": false}

Device Name Detection Logic

The passkeys endpoint intelligently determines device types:

  • internal transport → "Platform Authenticator" (Face ID, Touch ID, Windows Hello)
  • usb transport → "Security Key" (YubiKey, etc.)
  • ble/nfc transport → "Mobile Device"
  • Fallback → "Unknown Device"

Use Cases

  • Registration Flow: Check username availability before creating account
  • Account Management: Display all registered devices/passkeys
  • Security Audit: Monitor which devices have access
  • Support Tools: Help users identify and manage their passkeys

Technical Notes

  • Endpoints placed correctly in Express routing order (before :identifier routes)
  • URL encoding supported for special characters in usernames
  • No database schema changes required
  • Fully backward compatible

Deployment

  • ✅ Changes are already live on production (passkey.nuri.com)
  • ✅ Tested with real user data
  • ✅ No breaking changes

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added public endpoints to check if a username exists and to list a user’s passkeys, including readable device names and recent-use ordering, with consistent error handling.
  • Documentation
    • Updated section titles to reflect user query endpoints and retained dashboard/management endpoints.
    • Added a comprehensive API reference with endpoint groups, parameters, request/response examples, standardized error format, and guidance on rate limits, CORS, security, and device name logic.
    • Linked README to the full API documentation for easy navigation.

…skeys

## Summary
- Added GET /api/users/:username/exists endpoint to check if a username is registered
- Added GET /api/users/:username/passkeys endpoint to list all passkeys for a user
- Created comprehensive API documentation in docs/API.md

## Changes

### New Endpoints

#### Check User Existence
- **Endpoint**: GET /api/users/:username/exists
- **Purpose**: Verify if a username is already registered in the system
- **Response**: { "exists": true/false }
- **Use Case**: Pre-registration validation in client applications

#### List User Passkeys
- **Endpoint**: GET /api/users/:username/passkeys
- **Purpose**: Retrieve all registered passkeys for a specific user
- **Response**: Array of passkey objects with credentialId, deviceName, lastUsed, and createdAt
- **Features**:
  - Automatic device type detection based on transport methods
  - Sorted by most recently used
  - Returns 404 if user doesn't exist

### Device Name Logic
The endpoint intelligently determines device names based on:
- Transport type 'internal' → "Platform Authenticator" (Face ID, Touch ID, Windows Hello)
- Transport type 'usb' → "Security Key" (YubiKey, etc.)
- Transport types 'ble' or 'nfc' → "Mobile Device"
- Fallback to stored device_name or "Unknown Device"

### Documentation
- Created comprehensive API documentation in docs/API.md
- Updated README.md with references to new endpoints
- Added detailed request/response examples
- Included error handling scenarios

## Technical Details
- Endpoints positioned correctly in the Express routing order (before :identifier routes)
- Proper async/await error handling
- Consistent error response format
- URL-encoded username support (e.g., @ becomes %40)

## Testing
Tested on production server (https://passkey.nuri.com):
- ✅ User existence check working
- ✅ Passkey listing working with proper device name detection
- ✅ Error cases (non-existent users) handled correctly

## Deployment Notes
- Changes are live on production server at passkey.nuri.com
- No database schema changes required
- Backward compatible with existing functionality

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Aug 12, 2025

Walkthrough

Adds two public API endpoints for user existence and passkey listing in index.js, updates README section heading and endpoint listings, and introduces a comprehensive API reference at docs/API.md with endpoint details, examples, and guidance.

Changes

Cohort / File(s) Summary of Changes
API Implementation
index.js
Added GET /api/users/:username/exists and GET /api/users/:username/passkeys with validation, querying, formatting (device name inference, sorting), and standardized error handling/logging.
Documentation Updates
README.md, docs/API.md
Renamed a README section and listed new endpoints; added a cross-reference to docs/API.md. Introduced a new API reference covering endpoint groups, examples, error model, rate limits, CORS, security, and device name logic.

Sequence Diagram(s)

sequenceDiagram
  actor Client
  participant Server as API Server
  participant Store as User Store/DB

  rect rgb(235, 245, 255)
  note over Client,Server: Check username existence
  Client->>Server: GET /api/users/:username/exists
  Server->>Server: Validate username
  Server->>Store: Find user by username
  Store-->>Server: User record | null
  Server-->>Client: 200 { exists: true|false } or 400/500
  end

  rect rgb(245, 235, 255)
  note over Client,Server: List user passkeys
  Client->>Server: GET /api/users/:username/passkeys
  Server->>Server: Validate username
  Server->>Store: Get user and authenticators
  Store-->>Server: User + authenticators | null
  Server->>Server: Map transports→deviceName, format fields, sort by lastUsed
  Server-->>Client: 200 [passkeys[]] or 404/400/500
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15–20 minutes

Poem

I twitch my ears at APIs new,
Two fresh trails for users to pursue.
Exists? It squeaks a simple “true?”
Passkeys parade in tidy view.
Docs burrow deep, crisp and bright—
Carrots of clarity, day and night. 🥕✨

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch docs/api-documentation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
index.js (1)

791-817: Consider extracting device name logic into a utility function.

The device name determination logic is well-implemented but could be made more maintainable by extracting it into a separate utility function, especially if this logic might be reused elsewhere.

+// Utility function to determine device name from authenticator data
+function getDeviceName(auth) {
+  // If we have device info stored, use that
+  if (auth.device_name) {
+    return auth.device_name;
+  }
+  
+  // Try to determine device type from transports
+  if (auth.transports) {
+    if (auth.transports.includes('internal')) {
+      return 'Platform Authenticator';
+    } else if (auth.transports.includes('usb')) {
+      return 'Security Key';
+    } else if (auth.transports.includes('ble') || auth.transports.includes('nfc')) {
+      return 'Mobile Device';
+    }
+  }
+  
+  return 'Unknown Device';
+}

     // Format passkeys for response
     const passkeys = authenticators.map(auth => {
-      // Extract device name from transports or user agent if available
-      let deviceName = 'Unknown Device';
-      
-      // Try to determine device type from transports
-      if (auth.transports) {
-        if (auth.transports.includes('internal')) {
-          deviceName = 'Platform Authenticator';
-        } else if (auth.transports.includes('usb')) {
-          deviceName = 'Security Key';
-        } else if (auth.transports.includes('ble') || auth.transports.includes('nfc')) {
-          deviceName = 'Mobile Device';
-        }
-      }
-      
-      // If we have device info stored, use that
-      if (auth.device_name) {
-        deviceName = auth.device_name;
-      }
-      
       return {
         credentialId: Buffer.from(auth.credentialID).toString('base64url'),
-        deviceName: deviceName,
+        deviceName: getDeviceName(auth),
         lastUsed: auth.last_used || auth.updated_at || auth.created_at,
         createdAt: auth.created_at
       };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between adf4780 and 20b5a27.

📒 Files selected for processing (3)
  • README.md (1 hunks)
  • docs/API.md (1 hunks)
  • index.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

Dashboard should use window.location.origin for API_BASE instead of hardcoded https://localhost

Files:

  • index.js
🧬 Code Graph Analysis (1)
index.js (1)
db.js (1)
  • getAuthenticatorsByUserId (126-139)
🔇 Additional comments (8)
README.md (2)

228-231: LGTM - Clear documentation for new endpoints.

The section correctly documents the two new public API endpoints with appropriate formatting and clear naming. The section rename from "Dashboard & Management" to "User Query Endpoints" properly categorizes these user-facing endpoints.


238-238: LGTM - Helpful cross-reference to detailed API documentation.

The cross-reference line provides users with a clear path to find complete API documentation with examples and detailed specifications.

index.js (2)

750-767: LGTM - Well-implemented username existence check.

The endpoint correctly validates the username parameter, uses appropriate error handling, and returns a clear boolean response. The implementation follows the established patterns in the codebase.


769-833: LGTM - Comprehensive passkey listing implementation.

The endpoint implementation is well-structured with:

  • Proper input validation and error handling
  • Clear device name determination logic based on transport types
  • Appropriate data formatting (base64url for credential IDs)
  • Sorting by most recent usage as specified
  • Consistent logging and error responses

The device name mapping logic correctly follows the specification:

  • internal → "Platform Authenticator"
  • usb → "Security Key"
  • ble/nfc → "Mobile Device"
  • Fallback to stored device_name or "Unknown Device"
docs/API.md (4)

1-8: LGTM - Well-structured API documentation.

The documentation provides a clear table of contents with logical grouping of endpoints into Authentication, User Management, Data Storage, and Administrative categories.


108-130: LGTM - Clear documentation for user existence endpoint.

The endpoint documentation includes proper HTTP method, path parameters, response format, and a practical curl example with URL encoding.


133-186: LGTM - Comprehensive passkeys listing documentation.

The documentation thoroughly covers:

  • Request/response formats
  • Error handling scenarios
  • Device name determination logic
  • Practical examples with URL encoding
  • Clear explanation of the sorting behavior

The device name logic section is particularly helpful for understanding how device types are determined.


362-396: LGTM - Excellent documentation of error handling and security considerations.

The documentation provides comprehensive coverage of:

  • Consistent error response format
  • HTTP status codes
  • Rate limiting recommendations
  • CORS configuration notes
  • Security best practices

This is essential information for production deployments.

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.

1 participant