vendure-plugin-capjs
v1.0.2
Published
A Vendure plugin that integrates Cap.js for privacy-focused, lightweight CAPTCHA protection. Provides challenge/redeem endpoints and a guard decorator for protecting GraphQL mutations.
Maintainers
Readme
Capjs Plugin
A Vendure plugin that integrates Cap.js for privacy-focused, lightweight CAPTCHA protection. This plugin provides REST endpoints for challenge creation and redemption, along with a guard decorator for protecting GraphQL mutations.
Features
- Privacy-focused CAPTCHA: Uses Cap.js proof-of-work challenges instead of tracking-based solutions
- GraphQL protection: Easily protect any GraphQL mutation with a decorator
- REST endpoints:
/cap/challengeand/cap/redeemendpoints for frontend integration
Installation
npm install vendure-plugin-capjs @cap.js/serverConfiguration
Add the plugin to your Vendure config:
import { VendureConfig } from '@vendure/core';
import { CapjsPlugin } from 'vendure-plugin-capjs';
export const config: VendureConfig = {
// ... other config
plugins: [
CapjsPlugin.init({}),
// ... other plugins
],
};Database Migration
This plugin adds new entities (CapjsChallenges and CapjsToken) to your database. After adding the plugin to your config, you need to generate and run a database migration:
# Generate the migration
npm run migration:generate capjs-plugin
# Run the migration
npm run migration:runMake sure your Vendure config has migrations enabled:
export const config: VendureConfig = {
// ... other config
dbConnectionOptions: {
// ... other options
migrations: [/* your migrations */],
migrationsRun: false, // Set to true to run migrations automatically on startup
},
};Usage
REST Endpoints
The plugin exposes two REST endpoints:
Create Challenge
POST /cap/challengeReturns a new CAPTCHA challenge that the client must solve.
Redeem Challenge
POST /cap/redeem
Content-Type: application/json
{
"token": "<challenge-token>",
"solutions": [<solution-numbers>]
}Validates the solved challenge and returns a token for subsequent API calls.
Protecting GraphQL Mutations
Use the @CapjsValidate() decorator to protect any GraphQL mutation:
import { Mutation, Resolver } from '@nestjs/graphql';
import { CapjsValidate } from 'vendure-plugin-capjs';
@Resolver()
export class MyResolver {
@Mutation()
@CapjsValidate()
async submitForm() {
// This mutation is protected by CAPTCHA
// Will throw if x-captcha-token header is missing or invalid
}
}Frontend Integration
The client must:
- Request a challenge from
POST /cap/challenge - Solve the proof-of-work challenge using the @cap.js/widget or @cap.js/vanilla
- Submit solutions to
POST /cap/redeemto get a validation token - Include the token in the
x-captcha-tokenheader for protected GraphQL mutations
Example with the Cap.js widget:
<!-- Load the Cap.js widget script -->
<script src="https://cdn.jsdelivr.net/npm/@cap.js/widget"></script>
<!-- Add the widget to your form -->
<cap-widget id="cap" data-cap-api-endpoint="/cap"></cap-widget>
<script>
const widget = document.querySelector('#cap');
widget.addEventListener('solve', function (e) {
const token = e.detail.token;
// Include token in your GraphQL request headers
// headers: { 'x-captcha-token': token }
});
</script>For invisible mode (no visible widget):
import Cap from '@cap.js/widget';
const cap = new Cap({
apiEndpoint: '/cap/',
});
const token = await cap.solve();
// Use token in x-captcha-token headerAPI Reference
CapjsPlugin
CapjsPlugin.init(options: PluginInitOptions)Initializes the plugin with the given options.
CapjsValidate Decorator
@CapjsValidate()Decorator that applies the CapjsGuard to a resolver method. Validates the x-captcha-token header and throws a UserInputError if validation fails.
Error Codes
MISSING_CAPTCHA: Thex-captcha-tokenheader was not providedINVALID_CAPTCHA: The provided token failed validation
License
MIT
