@lock-dev/geo-block
Version:
Geographic blocking module for lock.dev security framework
54 lines (53 loc) • 1.71 kB
JavaScript
/**
* Create an edge-compatible geo-blocking middleware for Next.js
*
* @example
* ```typescript
* // middleware.ts
* import { createEdgeGeoBlock } from '@lock.dev/geo-block/edge';
*
* export default createEdgeGeoBlock({
* mode: 'blocklist',
* countries: ['RU', 'BY'],
* blockStatusCode: 451
* });
*
* export const config = {
* matcher: '/api/:path*',
* };
* ```
*/
export function createEdgeGeoBlock(config) {
const defaultConfig = {
mode: 'blocklist',
blockStatusCode: 403,
blockMessage: 'Access denied based on your location',
};
const fullConfig = { ...defaultConfig, ...config };
return function middleware(request) {
// This assumes Next.js Edge middleware request which has geo data
const country = request.geo?.country || '';
if (!country) {
// Can't determine country, allow by default
return;
}
const isBlocked = (fullConfig.mode === 'blocklist' && fullConfig.countries.includes(country)) ||
(fullConfig.mode === 'allowlist' && !fullConfig.countries.includes(country));
if (isBlocked) {
// Handle redirect if specified
if (fullConfig.redirectUrl) {
return Response.redirect(new URL(fullConfig.redirectUrl, request.url));
}
// Otherwise return error response
return new Response(JSON.stringify({
error: fullConfig.blockMessage,
country,
}), {
status: fullConfig.blockStatusCode,
headers: {
'Content-Type': 'application/json',
},
});
}
};
}