74echo "๐ Next steps:"
75echo " โข Deploy to Val Town: ./scripts/deploy.sh"
76echo " โข Test API manually: ./scripts/test-api.sh"
77exit 0
78else
location-feed-generatordeploy.sh10 matches
38fi
3940# Deploy HTTP API
41echo "2/3 Deploying anchorAPI (HTTP function)..."
42if vt create http anchorAPI --file src/api/anchor-api.ts; then
43echo "โ anchorAPI deployed successfully"
44API_URL=$(vt url anchorAPI)
45echo "๐ API available at: $API_URL"
46else
47echo "โ Failed to deploy anchorAPI"
48exit 1
49fi
63echo "๐ Deployment Summary:"
64echo "โโโ jetstreamPoller: Runs every 5 minutes to ingest check-ins"
65echo "โโโ anchorAPI: HTTP API for feeds and queries"
66echo "โโโ socialGraphSync: Runs daily at 2 AM UTC to sync social graph"
67echo ""
68echo "๐ Next steps:"
69echo "1. Test the API: ./scripts/test-api.sh"
70echo "2. Monitor logs: vt logs <function-name>"
71echo "3. Check function status: vt list"
72echo ""
73echo "๐ API URL: $API_URL"
ZenServertest-frontend-client.tsx29 matches
15<script src="https://esm.town/v/std/catch"></script>
16<style>
17@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
1819* {
87// Endpoints
88const SERVER_URL = 'https://6cda888e-d01d-4bd6-8bc7-ab237d4223f3-00-sjg2kdsts2w2.spock.replit.dev';
89const NONCE_PATH = '/api/create-payment-nonce';
90const HASH_PATH = '/api/create-payment-hash';
91const BOOKING_TOKEN_PATH = '/api/generate-booking-token';
92const NONCE_ENDPOINT = SERVER_URL + NONCE_PATH;
93const HASH_ENDPOINT = SERVER_URL + HASH_PATH;
353customerReference: generateGUID(),
354displayMode: '0',
355apikey: '',
356username: '',
357password: '',
359timestamp: getTimestamp(),
360email_verify: '', // ๐ฏ
361backendApiKey: 'demo_api_key_12345', // Enhanced security: Backend API key for dual auth
362});
363377useEffect(() => {
378setFingerprintPayload({
379apikey: formData.apikey,
380username: formData.username,
381password: formData.password,
416417const areCredentialsComplete = () => {
418return formData.apikey && formData.username && formData.password && formData.backendApiKey;
419};
420494console.log('๐ Fingerprint payload for hash:', fingerprintPayload);
495496const apiResponse = await fetch(HASH_ENDPOINT, {
497method: 'POST',
498headers: {
499'Content-Type': 'application/json',
500'Authorization': 'Bearer ' + formData.backendApiKey, // Enhanced security: API key required
501'X-Payment-Nonce': nonce,
502'Origin': window.location.origin,
507});
508509if (!apiResponse.ok) {
510const errorText = await apiResponse.text();
511let errorMsg;
512try {
513const errorData = JSON.parse(errorText);
514errorMsg = errorData.error || 'Hash API failed';
515} catch {
516errorMsg = 'Hash API returned ' + apiResponse.status;
517}
518throw new Error(errorMsg);
519}
520521const hashData = await apiResponse.json();
522hash = hashData.hash;
523console.log('โ Hash received successfully ๐');
526} catch (err) {
527const msg = err instanceof Error ? err.message : String(err);
528setPayError('Hash API failed: ' + msg);
529console.error('โ Hash API failed:', msg);
530setIsProcessing(false);
531prefetchNewNonce();
537const paymentPayload = {
538merchantCode: MERCHANT_CODE,
539apiKey: formData.apikey,
540fingerprint: hash,
541redirectUrl: window.location.href + '/redirect?',
639key: 'title',
640className: "text-xl font-semibold mb-4"
641}, '๐ API Credentials'),
642React.createElement('div', {
643key: 'inputs',
645}, [
646React.createElement(Input, {
647key: 'apikey',
648label: "Payment Gateway API Key",
649name: "apikey",
650value: formData.apikey,
651onChange: handleInputChange,
652icon: "๐"
653}),
654React.createElement(Input, {
655key: 'backendApiKey',
656label: "Backend API Key (Security)",
657name: "backendApiKey",
658value: formData.backendApiKey,
659onChange: handleInputChange,
660icon: "๐ก๏ธ"
753variant: 'warning',
754className: "mb-4"
755}, 'Please enter both Payment Gateway and Backend API credentials to enable tour selection'),
756areCredentialsComplete() && React.createElement(Alert, {
757key: 'security-info',
758variant: 'info',
759className: "mb-4"
760}, '๐ก๏ธ Enhanced Security: This demo uses dual authentication (nonce + API key) to prevent payment fingerprint harvesting attacks'),
761React.createElement('div', {
762key: 'tours-grid',
ZenServerschemaValidationService.ts16 matches
23/**
24* Dynamic schema validation service that validates requests/responses
25* against OpenAPI schemas for complete automation
26*/
27export class SchemaValidationService {
2930/**
31* Load schemas from OpenAPI specification
32*/
33static loadSchemas(openApiSpec: any): void {
34if (openApiSpec.components?.schemas) {
35this.schemas = openApiSpec.components.schemas;
36logger.info("Schemas loaded for validation", {
37schemaCount: Object.keys(this.schemas).length
47method: string,
48body: any,
49openApiSpec: any
50): ValidationResult {
51try {
52const pathSpec = openApiSpec.paths?.[endpoint]?.[method.toLowerCase()];
53if (!pathSpec?.requestBody?.content?.['application/json']?.schema) {
54return { valid: true, errors: [] }; // No schema to validate against
71statusCode: number,
72response: any,
73openApiSpec: any
74): ValidationResult {
75try {
76const pathSpec = openApiSpec.paths?.[endpoint]?.[method.toLowerCase()];
77const responseSpec = pathSpec?.responses?.[statusCode.toString()]?.content?.['application/json']?.schema;
78
8990/**
91* Core validation logic against OpenAPI schema
92*/
93private static validateAgainstSchema(
269270/**
271* Get rate limit from OpenAPI path specification
272*/
273static extractRateLimit(pathSpec: any): number | null {
281*/
282static requiresAuthentication(pathSpec: any): {
283requiresApiKey: boolean;
284requiresNonce: boolean;
285} {
286const security = pathSpec?.security || [];
287
288let requiresApiKey = false;
289let requiresNonce = false;
290291for (const securityReq of security) {
292if (securityReq.ApiKeyAuth) {
293requiresApiKey = true;
294}
295if (securityReq.NonceAuth) {
298}
299300return { requiresApiKey, requiresNonce };
301}
302}
ZenServerpaymentHandler.ts9 matches
91const origin = request.headers.get("origin") || "";
9293// Validate API key first (critical security - payment credentials involved)
94const apiValidation = AuthService.validateApiKey(request);
95if (!apiValidation.valid) {
96logger.warn("Unauthorized payment hash creation attempt", {
97ip,
98error: apiValidation.error,
99userAgent: request.headers.get("user-agent") || "unknown"
100});
101
102return addCorsHeaders(
103new Response(JSON.stringify({ error: apiValidation.error }), {
104status: 401,
105headers: { "Content-Type": "application/json" }
195// Generate payment hash
196const paymentRequest: PaymentHashRequest = {
197apikey: body.apikey,
198mode: body.mode,
199paymentAmount: body.paymentAmount,
325// Parse request body
326const body = await request.json();
327const { apikey, username, password, mode, paymentAmount, merchantUniquePaymentId, timestamp } = body;
328329// Validate all required parameters
330const requiredFields = ['apikey', 'username', 'password', 'mode', 'paymentAmount', 'merchantUniquePaymentId', 'timestamp'];
331const missingFields = requiredFields.filter(field => !body[field]);
332344// Create payment request with custom credentials
345const paymentRequest: PaymentHashRequest = {
346apikey,
347mode,
348paymentAmount,
ZenServeropenapi.yaml54 matches
1openapi: 3.0.3
2info:
3title: Secure Payment API
4description: |
5A secure payment API backend with token-based authentication, nonce-based security,
6and comprehensive security controls. Designed to prevent mass harvesting of payment
7fingerprints while maintaining secure shareable booking links.
9## Security Architecture
10- **Booking Access**: 256-bit secure tokens (24-hour expiry)
11- **Payment Security**: Nonce-based authentication with API key requirement
12- **Webhook Security**: API key authentication (header or query string)
13- **Rate Limiting**: Per-endpoint throttling (5-20 req/min)
14- **CORS Protection**: Origin validation and security headers
15version: 1.0.0
16contact:
17name: API Support
18email: api-support@yourdomain.com
19license:
20name: MIT
2223servers:
24- url: https://api.yourdomain.com
25description: Production server
26- url: https://staging-api.yourdomain.com
27description: Staging server
28- url: http://localhost:5000
3031security:
32- ApiKeyAuth: []
33- NonceAuth: []
3436/:
37get:
38summary: API documentation redirect
39description: Redirects to the interactive API documentation
40tags:
41- Documentation
43responses:
44'302':
45description: Redirect to API documentation
46headers:
47Location:
48schema:
49type: string
50example: "/api/docs"
5152/api/docs:
53get:
54summary: Interactive API documentation
55description: |
56Modern Swagger UI interface with comprehensive documentation,
61responses:
62'200':
63description: API documentation page
64content:
65text/html:
70get:
71summary: Health check endpoint
72description: Returns the health status of the API and all components
73tags:
74- System
76responses:
77'200':
78description: API is healthy
79content:
80application/json:
108$ref: '#/components/responses/NotFound'
109110/api/generate-booking-token:
111post:
112summary: Generate secure booking token (Admin)
113description: |
114Generate a new secure booking token for creating shareable links.
115**Requires API key authentication**.
116tags:
117- Bookings
118- Admin
119security:
120- ApiKeyAuth: []
121requestBody:
122required: true
141$ref: '#/components/responses/TooManyRequests'
142143/api/create-payment-nonce:
144post:
145summary: Generate payment nonce
171$ref: '#/components/responses/TooManyRequests'
172173/api/create-payment-hash:
174post:
175summary: Create payment fingerprint
176description: |
177Exchange valid nonce for payment gateway fingerprint.
178**CRITICAL SECURITY**: Requires both nonce and API key authentication.
179Server injects payment credentials securely.
180tags:
181- Payment
182security:
183- ApiKeyAuth: []
184- NonceAuth: []
185requestBody:
207$ref: '#/components/responses/TooManyRequests'
208209/api/generate-payment-hash:
210post:
211summary: Generate payment hash with custom credentials (Public Service)
212description: |
213Public service endpoint for generating SHA3-512 payment hashes using custom credentials.
214Users provide their own apikey, username, password, and payment details.
215**No authentication required** - designed as a public hash generation service.
216**Rate Limited**: 10 requests per minute per IP.
236$ref: '#/components/responses/TooManyRequests'
237238/api/v1/payment/refresh:
239post:
240summary: Refresh payment session
265$ref: '#/components/responses/TooManyRequests'
266267/api/v1/turnstile/verify:
268post:
269summary: Verify Cloudflare Turnstile token
297description: |
298Accepts any JSON payload for webhook processing.
299**Requires API key authentication** (header or query string).
300Returns processing confirmation with audit details.
301tags:
302- Webhooks
303security:
304- ApiKeyAuth: []
305requestBody:
306required: true
330description: |
331Identical to webhook endpoint for maximum flexibility.
332**Requires API key authentication** (header or query string).
333tags:
334- Webhooks
335security:
336- ApiKeyAuth: []
337requestBody:
338required: true
357$ref: '#/components/responses/TooManyRequests'
358359/openapi.yaml:
360get:
361summary: OpenAPI specification
362description: Raw OpenAPI 3.0.3 specification in YAML format
363tags:
364- Documentation
366responses:
367'200':
368description: OpenAPI specification
369content:
370application/yaml:
374components:
375securitySchemes:
376ApiKeyAuth:
377type: apiKey
378in: header
379name: Authorization
380description: |
381API key authentication using Bearer token format.
382
383**Header**: `Authorization: Bearer {api_key}`
384
385**Query Parameter**: `?api_key={api_key}` (fallback)
386
387Required for payment hash creation and webhook endpoints.
388389NonceAuth:
390type: apiKey
391in: header
392name: X-Payment-Nonce
550type: object
551properties:
552apikey:
553type: string
554description: Payment gateway API key
555example: 'LFc3-qneWUmL2bIWSSZZGA'
556mode:
575example: '2024-01-01T10:00:00'
576required:
577- apikey
578- mode
579- paymentAmount
584type: object
585properties:
586apikey:
587type: string
588description: Payment gateway API key
589example: 'LFc3-qneWUmL2bIWSSZZGA'
590username:
617example: '2024-01-01T10:00:00'
618required:
619- apikey
620- username
621- password
635type: string
636example: 'DEMO-MERCHANT'
637apiKey:
638type: string
639example: 'LFc3-qneWUmL2bIWSSZZGA'
658- fingerprint
659- merchantCode
660- apiKey
661- redirectUrl
662- mode
851tags:
852- name: Documentation
853description: API documentation and specification endpoints
854- name: System
855description: System health and status endpoints
863description: Generic webhook and callback processing
864- name: Admin
865description: Administrative endpoints requiring API key authentication
ZenServerDOCUMENTATION.md50 matches
1# Secure Payment API Documentation
23## Overview
45This secure payment API solves the critical problem of **payment fingerprint harvesting** while maintaining the business requirement of publicly shareable booking links. The system implements a multi-layered security architecture with token-based booking access and nonce-based payment protection.
67## The Core Problem
30D --> E[Payment Button Click]
31E --> F[Nonce Generation]
32F --> G[API Key + Nonce Validation]
33G --> H[Payment Fingerprint Creation]
34H --> I[Single-Use Protection]
38391. **Token-Based Booking Access** - 256-bit cryptographically secure tokens replace direct booking ID access
402. **Dual Authentication for Payments** - API key + nonce requirement for payment fingerprint creation
413. **Single-Use Nonces** - IP-bound, 15-minute expiry, marked as used immediately
424. **Environment Protection** - Server fails to start without required credentials
435. **Rate Limiting** - Per-endpoint throttling prevents abuse
446. **Input Validation** - Dynamic schema validation against OpenAPI specifications
4546## File Structure & Purpose
54โ โโโ schema.ts # Database schema with booking tokens & security tables
55โโโ gateway/
56โ โโโ apiGateway.ts # Centralized entry point - all routing & security control
57โโโ handlers/
58โ โโโ bookingHandler.ts # Token-based booking access & token generation
65โ โโโ security.ts # Pattern detection & suspicious activity monitoring
66โโโ services/
67โ โโโ authService.ts # Token generation & API key validation
68โ โโโ nonceService.ts # Cryptographically secure nonce management
69โ โโโ paymentService.ts # SHA3-512 fingerprint generation with server credentials
70โ โโโ schemaValidationService.ts # Dynamic OpenAPI schema validation
71โ โโโ validationService.ts # Input sanitization & format validation
72โโโ types/
74โโโ utils/
75โโโ logger.ts # Structured security event logging
76โโโ openApiLoader.ts # Dynamic OpenAPI specification loading
77โโโ sanitizer.ts # SQL injection prevention utilities
78```
84participant S as Server Start
85participant E as Environment
86participant G as API Gateway
87participant D as Database
88participant O as OpenAPI Loader
89participant L as Logger
9091S->>E: Validate Required Secrets
92Note over E: PAYMENT_USERNAME, PAYMENT_PASSWORD,<br/>MERCHANT_CODE, API_KEY
93E-->>S: โ Secrets Valid or โ Exit(1)
94
95S->>G: Initialize API Gateway
96G->>D: Initialize Database
97D->>D: Create Tables & Indexes
99D-->>G: โ Database Ready
100
101G->>O: Load OpenAPI Spec
102O->>O: Parse YAML & Validate
103O->>O: Extract Endpoints & Security
145G->>H: Route to Handler
146H->>H: Authentication Check
147Note over H: API Key / Token / Nonce
148H->>DB: Database Operations
149DB-->>H: Query Results
167168Note over A,DB: Token Generation (Admin)
169A->>S: POST /api/generate-booking-token
170Note over S: API Key Required
171S->>S: Validate API Key
172S->>S: Generate 256-bit Token
173S->>DB: Store Token + Booking ID + Expiry
183184**Client Requirements:**
185- **Admin**: Must provide API key in `Authorization: Bearer {key}` header
186- **Public Users**: No authentication required - just use the token URL
187196197Note over C,PG: Phase 1: Nonce Generation
198C->>S: POST /api/create-payment-nonce
199Note over S: Rate Limited: 5 req/min
200S->>S: Validate Booking ID
204205Note over C,PG: Phase 2: Payment Fingerprint Creation
206C->>S: POST /api/create-payment-hash
207Note over S: Dual Auth: API Key + Nonce
208S->>S: Validate API Key
209S->>S: Validate Nonce (exists, unused, not expired, IP match)
210S->>DB: Mark Nonce as USED
221- **Nonce Request**: Provide valid `bookingId` in request body
222- **Payment Hash**: Must include both:
223- `Authorization: Bearer {api_key}` header
224- `X-Payment-Nonce: {nonce}` header
225- Valid payment data (amount, merchantUniquePaymentId, timestamp)
234235Note over C,DB: Payment Failed - Need Fresh Session
236C->>S: POST /api/v1/payment/refresh
237S->>S: Validate Booking ID
238S->>DB: Invalidate Existing Nonces for Booking
243```
244245## API Reference
246247### Booking Endpoints
258```
259260#### POST /api/generate-booking-token
261**Purpose**: Generate secure shareable booking links (Admin only)
262**Authentication**: API Key required
263**Security**: Prevents unauthorized token generation
264265```javascript
266// Admin Usage
267const response = await fetch('/api/generate-booking-token', {
268method: 'POST',
269headers: {
270'Authorization': 'Bearer your_api_key',
271'Content-Type': 'application/json'
272},
278### Payment Endpoints
279280#### POST /api/create-payment-nonce
281**Purpose**: Generate single-use nonce for payment attempts
282**Authentication**: None (rate limited)
285```javascript
286// Frontend Usage
287const response = await fetch('/api/create-payment-nonce', {
288method: 'POST',
289headers: { 'Content-Type': 'application/json' },
293```
294295#### POST /api/create-payment-hash
296**Purpose**: Exchange nonce for payment fingerprint
297**Authentication**: API Key + Nonce required
298**Security**: Dual authentication prevents unauthorized access
299300```javascript
301// Frontend Usage - CRITICAL SECURITY
302const response = await fetch('/api/create-payment-hash', {
303method: 'POST',
304headers: {
305'Authorization': 'Bearer your_api_key',
306'X-Payment-Nonce': nonce,
307'Content-Type': 'application/json'
308},
309body: JSON.stringify({
310apikey: 'payment_gateway_key',
311mode: '0',
312paymentAmount: '1200.00',
318```
319320#### POST /api/v1/payment/refresh
321**Purpose**: Refresh payment session after failures
322**Authentication**: None (rate limited)
325```javascript
326// Frontend Usage - After Payment Failure
327const response = await fetch('/api/v1/payment/refresh', {
328method: 'POST',
329headers: { 'Content-Type': 'application/json' },
335### Security Endpoints
336337#### POST /api/v1/turnstile/verify
338**Purpose**: Verify Cloudflare Turnstile CAPTCHA token
339**Authentication**: None (rate limited)
342```javascript
343// Frontend Usage
344const response = await fetch('/api/v1/turnstile/verify', {
345method: 'POST',
346headers: { 'Content-Type': 'application/json' },
381```javascript
382class SecurePaymentFlow {
383constructor(apiKey) {
384this.apiKey = apiKey;
385}
386388try {
389// Step 1: Generate nonce
390const nonceResponse = await fetch('/api/create-payment-nonce', {
391method: 'POST',
392headers: { 'Content-Type': 'application/json' },
396397// Step 2: Create payment hash with dual authentication
398const hashResponse = await fetch('/api/create-payment-hash', {
399method: 'POST',
400headers: {
401'Authorization': `Bearer ${this.apiKey}`,
402'X-Payment-Nonce': nonce,
403'Content-Type': 'application/json'
404},
405body: JSON.stringify({
406apikey: 'payment_gateway_key',
407mode: '0',
408paymentAmount: amount,
451### POST /webhook
452**Purpose**: Process any JSON payload from external systems
453**Authentication**: API Key required
454**Usage**: Third-party system notifications
455456### POST /callback
457**Purpose**: Identical to webhook for maximum flexibility
458**Authentication**: API Key required
459**Usage**: Payment gateway callbacks, external service notifications
460468PAYMENT_PASSWORD=your_payment_gateway_password
469MERCHANT_CODE=your_merchant_code
470API_KEY=your_secure_api_key_256_bit
471```
472
ZenBackendenvironment.ts1 match
58REDIRECT_URL: getEnvVar("REDIRECT_URL", "https://yourdomain.com/payment/results"),
5960// API authentication
61WEBHOOK_SECRET: getEnvVarOptional("WEBHOOK_SECRET", "webhook_secret_2024"),
62SESSION_SECRET: getEnvVarOptional("SESSION_SECRET", "session_secret_2024"),
ESP32-FirmwareFlasherApp.tsx7 matches
5import { FlashControls } from './FlashControls.tsx';
6import { serialService } from '../services/serialService.ts';
7import { apiClient } from '../services/api.ts';
8import { FirmwareInfo, DeviceInfo, FlashProgress } from '../../shared/types.ts';
939
40// Load firmware list
41const firmwareResult = await apiClient.getFirmwareList();
42if (firmwareResult.success && firmwareResult.data) {
43setState(prev => ({
115
116// Download firmware
117const downloadResult = await apiClient.downloadFirmware(state.selectedFirmware.name);
118if (!downloadResult.success || !downloadResult.data) {
119throw new Error(downloadResult.error || 'Failed to download firmware');
147setState(prev => ({ ...prev, error: null }));
148
149const result = await apiClient.convertElfToBin(file, chipType);
150if (result.success) {
151// In a real implementation, you'd handle the converted binary
280</div>
281282{/* Web Serial API Support Check */}
283{!serialService.constructor.isSupported() && (
284<div className="mt-8 bg-yellow-50 border border-yellow-200 rounded-lg p-6">
289<div className="ml-3">
290<h3 className="text-sm font-medium text-yellow-800">
291Web Serial API Not Supported
292</h3>
293<div className="mt-2 text-sm text-yellow-700">
294<p>
295Your browser doesn't support the Web Serial API. Please use a supported browser:
296</p>
297<ul className="list-disc list-inside mt-2">
ZenBackendmain.ts4 matches
1import { serve } from "https://deno.land/std@0.208.0/http/server.ts";
2import { ApiGateway } from "./src/gateway/apiGateway.ts";
3import { environment } from "./src/config/environment.ts";
45// Initialize the centralized API Gateway
6const gateway = new ApiGateway();
7await gateway.initialize();
89// Centralized router function - delegates to API Gateway
10async function router(request: Request): Promise<Response> {
11return await gateway.handleRequest(request);