# Strapi Plugin: API Select Field

A powerful and secure Strapi v4+ plugin that adds a reusable and configurable custom field to the Content-Type Builder. This plugin allows users to select options (single or multiple) dynamically fetched from external APIs, supporting both public and secure/private endpoints.

## 🎯 Features

- **Dynamic API Integration**: Fetch options from any external API endpoint
- **Flexible Selection Modes**: Support for both single and multiple selection
- **Secure Authentication**: Backend proxy for private APIs with proper authentication
- **Configurable Field Mapping**: Customize label and value keys from API responses
- **Search & Filtering**: Built-in search functionality with debounced API calls
- **Error Handling**: Comprehensive error handling with user-friendly messages
- **Security First**: SSRF protection, input sanitization, and secure proxy implementation
- **Production Ready**: Follows Strapi plugin standards and best practices

## 🚀 Installation

### Via npm

```bash
npm install api-select-field
```

### Via yarn

```bash
yarn add api-select-field
```

### Manual Installation

1. Clone this repository into your Strapi project's `plugins` folder:
```bash
cd plugins
git clone https://github.com/yourusername/api-select-field.git
```

2. Install dependencies:
```bash
cd api-select-field
npm install
```

3. Rebuild your Strapi admin panel:
```bash
npm run build
```

### Enable the Plugin

After installation, you must enable the plugin in your Strapi configuration:

1. Create or update `config/plugins.js` in your Strapi project:
```javascript
module.exports = {
  'api-select-field': {
    enabled: true,
    config: {
      timeout: 10000, // 10 seconds
      maxResults: 1000,
      cacheDuration: 300000, // 5 minutes
    },
  },
};
```

2. **Restart your Strapi server** after making configuration changes.

### Troubleshooting

**If you can't see the plugin in the Content-Type Builder:**

1. **Check if the plugin is enabled** in `config/plugins.js`
2. **Restart your Strapi server** after configuration changes
3. **Verify the plugin is installed** by checking `package.json` dependencies
4. **Check the server console** for any error messages during startup
5. **Ensure you're using Strapi v4+** (this plugin is not compatible with v3)

**Common Issues:**
- Plugin not appearing: Usually means the plugin isn't enabled or the server needs a restart
- Build errors: Make sure all dependencies are installed (`npm install`)
- Permission errors: Ensure the plugin has proper access to the Strapi instance

## 📖 Usage

### 1. Content-Type Configuration

Add the custom field to your Content Types in the Strapi admin panel:

```json
{
  "attributes": {
    "country": {
      "type": "customField",
      "customField": "plugin::api-select-field.api-select-field",
      "customFieldConfig": {
        "optionsApi": "https://restcountries.com/v3.1/all",
        "optionLabelKey": "name.common",
        "optionValueKey": "cca2",
        "selectMode": "single",
        "authMode": "public",
        "placeholder": "Select a country...",
        "description": "Choose a country from the list"
      }
    }
  }
}
```

### 2. Field Configuration Options

| Option | Type | Required | Default | Description |
|--------|------|----------|---------|-------------|
| `optionsApi` | string | ✅ | - | URL of the API to fetch options from |
| `optionLabelKey` | string | ❌ | `name` | Key in API response to use as display label |
| `optionValueKey` | string | ❌ | `id` | Key in API response to use as value |
| `selectMode` | enum | ❌ | `single` | `single` or `multiple` selection |
| `authMode` | enum | ❌ | `public` | `public` or `proxy` authentication |
| `placeholder` | string | ❌ | - | Placeholder text for the select field |
| `description` | string | ❌ | - | Help text for the field |

### 3. Authentication Modes

#### Public Mode (`authMode: "public"`)
- Direct API calls from the frontend
- Suitable for public APIs with CORS enabled
- Faster response times
- No backend proxy required

#### Proxy Mode (`authMode: "proxy"`)
- Secure backend proxy for private APIs
- API keys and tokens stored securely in environment variables
- Prevents exposure of sensitive credentials
- Recommended for production use with private APIs

## 🔐 Security Features

### SSRF Protection
- URL validation and sanitization
- Blocked localhost and private IP ranges
- Protocol validation (HTTP/HTTPS only)

### Secure Proxy Implementation
- Admin-only access to proxy endpoints
- Request logging and auditing
- Input sanitization and validation
- Environment variable-based configuration

### Best Practices
- Never expose API keys in frontend code
- Use HTTPS for all API communications
- Implement proper CORS policies
- Regular security audits and updates

## 🌍 Environment Variables

For proxy mode, configure these environment variables:

```bash
# Proxy Configuration (optional)
HTTP_PROXY=true
HTTP_PROXY_HOST=proxy.example.com
HTTP_PROXY_PORT=8080
HTTP_PROXY_AUTH=true
HTTP_PROXY_USERNAME=username
HTTP_PROXY_PASSWORD=password

# API-specific tokens (store securely)
EXTERNAL_API_TOKEN=your_api_token_here
```

## 📝 Example Configurations

### Public API Example (Countries)

```json
{
  "optionsApi": "https://restcountries.com/v3.1/all",
  "optionLabelKey": "name.common",
  "optionValueKey": "cca2",
  "selectMode": "single",
  "authMode": "public",
  "placeholder": "Select a country..."
}
```

### Private API Example (Users)

```json
{
  "optionsApi": "https://api.example.com/users",
  "optionLabelKey": "fullName",
  "optionValueKey": "userId",
  "selectMode": "multiple",
  "authMode": "proxy",
  "placeholder": "Select users..."
}
```

### Grouped Options Example

```json
{
  "optionsApi": "https://api.example.com/categories",
  "optionLabelKey": "categoryName",
  "optionValueKey": "categoryId",
  "optionGroupKey": "groupName",
  "selectMode": "single",
  "authMode": "proxy"
}
```

## 🛠️ Development

### Prerequisites
- Node.js >= 16.0.0
- Strapi v4+
- npm or yarn

### Local Development

1. Clone the repository:
```bash
git clone https://github.com/yourusername/strapi-plugin-api-select-field.git
cd strapi-plugin-api-select-field
```

2. Install dependencies:
```bash
npm install
```

3. Link to your Strapi project:
```bash
npm link
cd /path/to/your/strapi/project
npm link strapi-plugin-api-select-field
```

4. Build and start:
```bash
npm run build
npm run develop
```

### Testing

```bash
# Run tests
npm test

# Run tests in watch mode
npm run test:watch

# Lint code
npm run lint

# Fix linting issues
npm run lint:fix

# Format code
npm run format
```

## 📦 Building for Production

```bash
# Build the plugin
npm run build

# The built files will be in the `dist` folder
```

## 🔧 Troubleshooting

### Common Issues

1. **Field not appearing in Content-Type Builder**
   - Ensure the plugin is properly installed and built
   - Check Strapi version compatibility
   - Verify plugin registration in `config/plugins.js`

2. **API calls failing**
   - Check CORS settings for public APIs
   - Verify API endpoint accessibility
   - Check network connectivity and firewall settings

3. **Proxy mode not working**
   - Ensure user has admin authentication
   - Check environment variable configuration
   - Verify proxy endpoint accessibility

### Debug Mode

Enable debug logging by setting the log level in your Strapi configuration:

```javascript
// config/logger.js
module.exports = {
  level: 'debug',
  // ... other config
};
```

## 🤝 Contributing

We welcome contributions! Please follow these steps:

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

### Development Guidelines

- Follow Strapi plugin development standards
- Write comprehensive tests for new features
- Update documentation for any changes
- Follow the existing code style and conventions
- Ensure all tests pass before submitting PR

## 📄 License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

## 🙏 Acknowledgments

- Strapi team for the excellent plugin architecture
- Contributors and users of this plugin
- Open source community for inspiration and feedback

## 📞 Support

- **Issues**: [GitHub Issues](https://github.com/yourusername/strapi-plugin-api-select-field/issues)
- **Discussions**: [GitHub Discussions](https://github.com/yourusername/strapi-plugin-api-select-field/discussions)
- **Documentation**: [GitHub Wiki](https://github.com/yourusername/strapi-plugin-api-select-field/wiki)

## 🔄 Changelog

### v1.0.0
- Initial release
- Support for single and multiple selection
- Public and proxy authentication modes
- Comprehensive security features
- Full Strapi v4+ compatibility

---

**Made with ❤️ for the Strapi community**

*This plugin follows OWASP security guidelines and is designed for production use in enterprise environments.* 