feat: add Queue-based async server provisioning
- Add Cloudflare Queue for async server provisioning workflow - Implement VPS provider abstraction (Linode, Vultr) - Add provisioning API endpoints with API key authentication - Fix race condition in balance deduction (atomic query) - Remove root_password from Queue for security (fetch from DB) - Add IP assignment wait logic after server creation - Add rollback/refund on all failure cases Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,36 @@ export function jsonResponse<T>(
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create error response
|
||||
*/
|
||||
export function createErrorResponse(
|
||||
message: string,
|
||||
status: number,
|
||||
code?: string,
|
||||
corsHeaders: Record<string, string> = {}
|
||||
): Response {
|
||||
return jsonResponse(
|
||||
{
|
||||
error: message,
|
||||
code: code || 'ERROR',
|
||||
},
|
||||
status,
|
||||
corsHeaders
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create success response
|
||||
*/
|
||||
export function createSuccessResponse<T>(
|
||||
data: T,
|
||||
status: number = 200,
|
||||
corsHeaders: Record<string, string> = {}
|
||||
): Response {
|
||||
return jsonResponse(data, status, corsHeaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to get allowed CORS origin
|
||||
*/
|
||||
@@ -61,3 +91,34 @@ export function getAllowedOrigin(request: Request): string {
|
||||
// Browser will block the response due to CORS mismatch
|
||||
return allowedOrigins[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate request origin for sensitive endpoints (e.g., provision)
|
||||
* Only allows requests from *.kappa-d8e.workers.dev or worker-to-worker calls
|
||||
*/
|
||||
export function isAllowedProvisionOrigin(request: Request): boolean {
|
||||
const origin = request.headers.get('Origin');
|
||||
const referer = request.headers.get('Referer');
|
||||
|
||||
// Allow worker-to-worker calls (Cloudflare adds this header)
|
||||
// Note: This header indicates the request came from another Cloudflare Worker
|
||||
const cfWorker = request.headers.get('CF-Worker');
|
||||
if (cfWorker) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If no Origin header (server-to-server, curl, etc.) - check Referer or allow
|
||||
// For strict mode, you might want to reject these too
|
||||
if (!origin) {
|
||||
// Check Referer as fallback
|
||||
if (referer && referer.includes('.kappa-d8e.workers.dev')) {
|
||||
return true;
|
||||
}
|
||||
// Allow server-to-server for now (can be made stricter with API key)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check if Origin is from allowed domain
|
||||
const allowedPattern = /^https:\/\/[a-zA-Z0-9-]+\.kappa-d8e\.workers\.dev$/;
|
||||
return allowedPattern.test(origin);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
export {
|
||||
escapeHtml,
|
||||
jsonResponse,
|
||||
getAllowedOrigin
|
||||
getAllowedOrigin,
|
||||
isAllowedProvisionOrigin
|
||||
} from './http';
|
||||
|
||||
// Validation utilities (type guards, request validation)
|
||||
|
||||
Reference in New Issue
Block a user