Val Town Code SearchReturn to Val Town

API Access

You can access search results via JSON API by adding format=json to your query:

https://codesearch.val.run/image-url.jpg%20%22Optional%20title%22?q=api&page=127&format=json

For typeahead suggestions, use the /typeahead endpoint:

https://codesearch.val.run/typeahead?q=api

Returns an array of strings in format "username" or "username/projectName"

Found 25377 results for "api"(6745ms)

ZenAPIServer_hmac.ts.bak34 matches

@ianmenethilโ€ขUpdated 2 weeks ago
2/// <reference lib="deno.ns" />
3
4import { z } from "npm:@hono/zod-openapi";
5import type { Context, Next } from "npm:hono";
6import { createMiddleware } from "npm:hono/factory";
90 .describe("HMAC signature for request validation")
91 .meta({
92 openapi: {
93 description: "HMAC-SHA256 signature of the request payload",
94 example: "dG9rXzEyMzQ1Njc4OTBhYmNkZWY=",
102 .describe("Request timestamp for replay protection")
103 .meta({
104 openapi: {
105 description: "Unix timestamp when the request was created",
106 example: "1736999800",
114 .describe("Unique request identifier")
115 .meta({
116 openapi: {
117 description: "Unique identifier for the request",
118 example: "req_550e8400-e29b-41d4-a716-446655440000",
126 .describe("Device identifier")
127 .meta({
128 openapi: {
129 description: "Unique identifier for the client device",
130 example: "dev_1234567890abcdef",
138 .describe("Application identifier")
139 .meta({
140 openapi: {
141 description: "Identifier for the client application",
142 example: "com.example.mobileapp",
150 .describe("Application version")
151 .meta({
152 openapi: {
153 description: "Version of the client application",
154 example: "1.2.3",
168 .describe("Validated request timestamp")
169 .meta({
170 openapi: {
171 description: "Unix timestamp that passed validation",
172 example: "1736999800",
178 .describe("Validated request identifier")
179 .meta({
180 openapi: {
181 description: "Unique request identifier that passed validation",
182 example: "req_550e8400-e29b-41d4-a716-446655440000",
188 .describe("Validated device identifier")
189 .meta({
190 openapi: {
191 description: "Device identifier that passed validation",
192 example: "dev_1234567890abcdef",
198 .describe("Validated application identifier")
199 .meta({
200 openapi: {
201 description: "Application identifier that passed validation",
202 example: "com.example.mobileapp",
208 .describe("Validated HMAC signature")
209 .meta({
210 openapi: {
211 description: "HMAC signature that passed validation",
212 example: "dG9rXzEyMzQ1Njc4OTBhYmNkZWY=",
218 .describe("Validated application version")
219 .meta({
220 openapi: {
221 description: "Application version that passed validation",
222 example: "1.2.3",
234 .describe("Verification success status")
235 .meta({
236 openapi: {
237 description: "Whether the HMAC verification was successful",
238 example: true,
244 .optional()
245 .meta({
246 openapi: {
247 description: "Validated request headers (only present on success)",
248 example: {
261 .optional()
262 .meta({
263 openapi: {
264 description: "Original request body content (only present on success)",
265 example: '{"amount": 2500, "currency": "USD"}',
271 .optional()
272 .meta({
273 openapi: {
274 description: "Reason for verification failure (only present on failure)",
275 example: "Request timestamp expired or invalid",
288 .describe("Webhook event type")
289 .meta({
290 openapi: {
291 description: "Type of webhook event",
292 example: "payment.completed",
302 .describe("Payment identifier")
303 .meta({
304 openapi: {
305 description: "Unique identifier for the payment",
306 example: "pay_1234567890abcdef",
312 .describe("Merchant reference")
313 .meta({
314 openapi: {
315 description: "Merchant's reference for the payment",
316 example: "order_12345",
324 .describe("Payment amount in cents")
325 .meta({
326 openapi: {
327 description: "Payment amount in cents (e.g., 2500 = $25.00)",
328 example: 2500,
335 .describe("Payment currency")
336 .meta({
337 openapi: {
338 description: "Three-letter currency code",
339 example: "AUD",
347 .describe("Event timestamp")
348 .meta({
349 openapi: {
350 description: "ISO 8601 timestamp when the event occurred",
351 example: "2024-01-15T10:30:00Z",
358 .optional()
359 .meta({
360 openapi: {
361 description: "Additional metadata for the payment",
362 example: {
376 .describe("Request success status")
377 .meta({
378 openapi: {
379 description: "Always false for HMAC error responses",
380 example: false,
385 .describe("HMAC error message")
386 .meta({
387 openapi: {
388 description: "Human-readable HMAC error message",
389 example: "Invalid HMAC signature",
396 .describe("HMAC error code")
397 .meta({
398 openapi: {
399 description: "Machine-readable HMAC error code",
400 example: "HMAC_VERIFICATION_FAILED",
414 .describe("Error timestamp")
415 .meta({
416 openapi: {
417 description: "ISO 8601 timestamp when the error occurred",
418 example: "2024-01-15T10:30:00Z",
642/**
643 * Generate Generic HMAC Signature Function
644 * @description Creates HMAC-SHA256 signature for any data using Web Crypto API
645 *
646 * **HMAC Generation Process:**
647 * 1. **Text Encoding**: Converts data and secret to UTF-8 bytes
648 * 2. **Key Import**: Imports secret as HMAC-SHA256 crypto key
649 * 3. **Signature Creation**: Generates HMAC signature using Web Crypto API
650 * 4. **Base64 Encoding**: Converts signature bytes to base64 string
651 *
652 * **Security Features:**
653 * - ๐Ÿ”’ **Web Crypto API**: Uses browser's native cryptographic functions
654 * - ๐Ÿ›ก๏ธ **HMAC-SHA256**: Industry-standard HMAC algorithm
655 * - โšก **Secure Key Handling**: Proper key import and management
672 *
673 * > [!note]
674 * **Note**: Uses Web Crypto API for optimal performance and security.
675 *
676 * @type {Utility Function}
795 * **Usage Example:**
796 * ```typescript
797 * app.use("/api/v1/mobile/*", verifyHMACWithHeadersMiddleware);
798 * // Later in handlers:
799 * const headers = c.get("validatedHeaders");
872 * **Usage Example:**
873 * ```typescript
874 * app.use("/api/v1/webhooks/*", verifyHMACMiddleware);
875 * // Later in handlers:
876 * const body = c.get("requestBody");

ZenAPIServer_externalApiRequestOps.ts.bak5 matches

@ianmenethilโ€ขUpdated 2 weeks ago
1// /// <reference no-default-lib="true" />
2// /// <reference lib="deno.ns" />
3// /** v2 ExternalAPIRequestOps */
4// import { secureDBv2 } from "./dbCore.ts";
5// import { SQL_TABLES } from "./dbSchema.ts";
6
7// export class ExternalAPIRequestOpsV2 {
8// private static instance: ExternalAPIRequestOpsV2; private constructor() { }
9// static getInstance(): ExternalAPIRequestOpsV2 { if (!ExternalAPIRequestOpsV2.instance) ExternalAPIRequestOpsV2.instance = new ExternalAPIRequestOpsV2(); return ExternalAPIRequestOpsV2.instance; }
10
11// async track(deviceId: string, appId: string, appVersion: string, ipAddress: string, requestId: string, signature: string, responseStatus: number, processingTimeMs: number): Promise<void> {
49// }
50
51// export const externalAPIRequestsV2 = () => ExternalAPIRequestOpsV2.getInstance();
52

ZenAPIServer_crypto.ts.bak15 matches

@ianmenethilโ€ขUpdated 2 weeks ago
2/// <reference lib="deno.ns" />
3
4import { z } from "npm:@hono/zod-openapi";
5import type { Context } from "npm:hono";
6import { createMiddleware } from "npm:hono/factory";
39 .describe("Original client IP from Cloudflare")
40 .meta({
41 openapi: {
42 description: "Original client IP address as seen by Cloudflare",
43 example: "203.0.113.1",
55 .describe("Comma-separated list of IP addresses in proxy chain")
56 .meta({
57 openapi: {
58 description: "Comma-separated list of IP addresses: client, proxy1, proxy2, ...",
59 example: "203.0.113.1, 10.0.0.1, 172.16.0.1",
76 .describe("Real client IP address")
77 .meta({
78 openapi: {
79 description: "Real client IP address as determined by the proxy",
80 example: "203.0.113.1",
92 .describe("Resolved client IP address")
93 .meta({
94 openapi: {
95 description: "Best available client IP address from headers or connection",
96 example: "203.0.113.1",
108 .describe("Source of the IP address")
109 .meta({
110 openapi: {
111 description: "Source header or method used to determine the client IP",
112 example: "cf-connecting-ip",
126 .describe("IP extraction timestamp")
127 .meta({
128 openapi: {
129 description: "Unix timestamp when the IP was extracted",
130 example: 1736999800,
142 .describe("Request success status")
143 .meta({
144 openapi: {
145 description: "Always false for IP detection error responses",
146 example: false,
151 .describe("IP detection error message")
152 .meta({
153 openapi: {
154 description: "Human-readable IP detection error message",
155 example: "Failed to extract client IP address",
162 .describe("IP detection error code")
163 .meta({
164 openapi: {
165 description: "Machine-readable IP detection error code",
166 example: "IP_EXTRACTION_FAILED",
177 .describe("Fallback IP address used")
178 .meta({
179 openapi: {
180 description: "Fallback IP address used when extraction fails",
181 example: "0.0.0.0",
188 .describe("Error timestamp")
189 .meta({
190 openapi: {
191 description: "ISO 8601 timestamp when the error occurred",
192 example: "2024-01-15T10:30:00Z",
285/**
286 * @fileoverview Unified Cryptographic Utilities
287 * @description Centralized cryptographic operations using Hono utilities and Web Crypto API
288 * @version 1.0.0
289 */
292
293/* โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
294 5) Secure Random Generation (Using Web Crypto API)
295 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ */
296
297/**
298 * Generate Secure UUID Function
299 * @description Generates RFC 4122 compliant UUID v4 using Web Crypto API
300 * type {Utility Function}
301 * @returns {string} RFC 4122 compliant UUID v4 string

ZenAPIServer_cors.ts.bak.bak4 matches

@ianmenethilโ€ขUpdated 2 weeks ago
2 * @fileoverview Security - CORS (Cross-Origin Resource Sharing) Management
3 *
4 * Complete CORS implementation for the Hono + Zod + OpenAPI architecture following proper
5 * security patterns. Provides configurable CORS policies, origin validation, and comprehensive
6 * logging for different application contexts (main, webhook, admin, credentials mode).
469 * const adminCORS = createCORSMiddleware(ADMIN_CORS_POLICY);
470 *
471 * app.use('/api/*', mainCORS);
472 * app.use('/admin/*', adminCORS);
473 * ```
599 * **Usage:**
600 * ```typescript
601 * app.use("/api/secure/*", corsCredentialsMode);
602 * ```
603 *
691 * ```typescript
692 * const customPolicy = createCustomCORSPolicy({
693 * name: 'api-v2',
694 * allowedOrigins: ['https://app.example.com'],
695 * allowedMethods: ['GET', 'POST'],

ZenAPIServer_cors.ts.bak4 matches

@ianmenethilโ€ขUpdated 2 weeks ago
2 * @fileoverview Security - CORS (Cross-Origin Resource Sharing) Management
3 *
4 * Complete CORS implementation for the Hono + Zod + OpenAPI architecture following proper
5 * security patterns. Provides configurable CORS policies, origin validation, and comprehensive
6 * logging for different application contexts (main, webhook, admin, credentials mode).
400 * const adminCORS = createCORSMiddleware(ADMIN_CORS_POLICY);
401 *
402 * app.use('/api/*', mainCORS);
403 * app.use('/admin/*', adminCORS);
404 * ```
578 * **Usage:**
579 * ```typescript
580 * app.use("/api/secure/*", corsCredentialsMode);
581 * ```
582 *
685 * ```typescript
686 * const customPolicy = createCustomCORSPolicy({
687 * name: 'api-v2',
688 * allowedOrigins: ['https://app.example.com'],
689 * allowedMethods: ['GET', 'POST'],

ZenAPIServer_context.ts.bak2 matches

@ianmenethilโ€ขUpdated 2 weeks ago
195 PAGE_NONCES: 'pageNonces',
196
197 // API Key Authentication (set by API key middleware)
198 ACCESS_KEY_CONFIG: 'accessKeyConfig',
199
230
231 // ZenPay Integration
232 ZENPAY_API_KEY: 'ZENPAY_API_KEY',
233 ZENPAY_USERNAME: 'ZENPAY_USERNAME',
234 ZENPAY_PASSWORD: 'ZENPAY_PASSWORD',

ZenAPIServer_booking.getById.ts.bak48 matches

@ianmenethilโ€ขUpdated 2 weeks ago
3 *
4 * Retrieves a single booking resource using its UUID identifier
5 * Following EXACTLY the hono-zod-openapi-correct-usage.md patterns
6 *
7 * ## Component Category
21 */
22
23import { createRoute, z, type RouteHandler } from 'npm:@hono/zod-openapi';
24import type { AppEnv } from '../types/index.ts';
25import { BookingData } from './_booking.create.ts.bak.ts'; // Import from booking.create.ts where it's defined
48 INTERNAL_ERROR: 'Internal server error',
49 },
50 API_EXAMPLES: {
51 BOOKING_ID: '550e8400-e29b-41d4-a716-446655440000',
52 TOUR_ID: 'tour_reef_001',
67} as const;
68
69// Define response envelope schemas with .openapi() - NOT .meta()
70const OkEnvelopeSchema = z.object({
71 success: z.literal(true)
72 .describe('Always true on successful booking retrieval')
73 .openapi({
74 example: true,
75 description: 'Indicates the request succeeded',
77 data: BookingData
78 .describe('Booking resource payload')
79 .openapi({
80 description: 'Full booking record with all fields',
81 }),
82}).openapi('BookingResponse');
83
84const NotFoundEnvelopeSchema = z.object({
87 .max(BOOKING_GET_BY_ID_CONSTANTS.VALIDATION_LIMITS.MAX_MESSAGE_LENGTH)
88 .describe('Human readable not found message')
89 .openapi({
90 example: BOOKING_GET_BY_ID_CONSTANTS.ERROR_MESSAGES.BOOKING_NOT_FOUND,
91 minLength: BOOKING_GET_BY_ID_CONSTANTS.VALIDATION_LIMITS.MIN_MESSAGE_LENGTH,
92 maxLength: BOOKING_GET_BY_ID_CONSTANTS.VALIDATION_LIMITS.MAX_MESSAGE_LENGTH,
93 }),
94}).openapi('BookingNotFound');
95
96const BookingErrorSchema = z.object({
97 message: z.string()
98 .describe('Error message describing the failure')
99 .openapi({
100 example: BOOKING_GET_BY_ID_CONSTANTS.ERROR_MESSAGES.INTERNAL_ERROR,
101 }),
102}).openapi('BookingError');
103
104// Define path parameter schema
107 .uuid()
108 .describe('Booking UUID v4')
109 .openapi({
110 description: 'Unique booking identifier (UUID v4)',
111 example: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.BOOKING_ID,
112 format: 'uuid',
113 pattern: BOOKING_GET_BY_ID_CONSTANTS.PATTERNS.UUID_SIMPLE,
114 }),
115}).openapi('BookingParams');
116
117// Create booking retrieval route
118export const getBookingByIdRoute = createRoute({
119 method: 'get',
120 path: '/api/v1/bookings/:id', // Hono param syntax (colon); OpenAPI generator will convert
121 tags: ['Bookings', 'Retrieval'],
122 summary: 'Get booking by ID',
141### Usage Example
142\`\`\`bash
143curl -X GET "https://api.example.com/api/v1/bookings/550e8400-e29b-41d4-a716-446655440000" \\
144 -H "Accept: application/json"
145\`\`\`
215 success: true,
216 data: {
217 id: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.BOOKING_ID,
218 tourId: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.TOUR_ID,
219 title: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.TITLE,
220 description: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.DESCRIPTION,
221 paymentAmount: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.PAYMENT_AMOUNT,
222 customerName: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.CUSTOMER_NAME,
223 customerEmail: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.CUSTOMER_EMAIL,
224 bookingDate: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.BOOKING_DATE,
225 numberOfPeople: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.NUMBER_OF_PEOPLE,
226 totalAmount: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.TOTAL_AMOUNT,
227 status: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.STATUS,
228 paymentStatus: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.PAYMENT_STATUS,
229 sessionId: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.SESSION_ID,
230 createdAt: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.CREATED_AT,
231 updatedAt: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.UPDATED_AT,
232 },
233 },
274 * @example
275 * ```typescript
276 * app.openapi(getBookingByIdRoute, getBookingByIdHandler);
277 * ```
278 * @since 1.0.0
282 // PLACEHOLDER: In real app, this would validate path parameters and query repository
283 // Mock parameter validation and booking lookup for testing purposes
284 const mockId = BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.BOOKING_ID;
285
286 // PLACEHOLDER: In real app, this would be: const { id } = c.req.valid("param");
298 // Mock booking repository lookup for testing purposes
299 const mockBooking = {
300 id: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.BOOKING_ID,
301 tourId: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.TOUR_ID,
302 title: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.TITLE,
303 description: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.DESCRIPTION,
304 paymentAmount: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.PAYMENT_AMOUNT,
305 customerName: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.CUSTOMER_NAME,
306 customerEmail: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.CUSTOMER_EMAIL,
307 bookingDate: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.BOOKING_DATE,
308 numberOfPeople: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.NUMBER_OF_PEOPLE,
309 totalAmount: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.TOTAL_AMOUNT,
310 status: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.STATUS,
311 paymentStatus: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.PAYMENT_STATUS,
312 firstName: 'Jane',
313 lastName: 'Doe',
319 subscribeNewsletter: 1,
320 acceptTerms: 1,
321 sessionId: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.SESSION_ID,
322 createdAt: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.CREATED_AT,
323 updatedAt: BOOKING_GET_BY_ID_CONSTANTS.API_EXAMPLES.UPDATED_AT,
324 };
325

ZenAPIServer_booking.create.ts.bak136 matches

@ianmenethilโ€ขUpdated 2 weeks ago
3 *
4 * Creates new tour bookings with JWT-CSRF authentication, honeypot validation, and pricing calculation
5 * Following EXACTLY the hono-zod-openapi-correct-usage.md patterns
6 *
7 * ## Component Category
21 */
22
23import { createRoute, z, type RouteHandler } from 'npm:@hono/zod-openapi';
24import type { AppEnv } from '../types/index.ts';
25
65 INVALID_DATE_FORMAT: 'Date must be in YYYY-MM-DD format',
66 },
67 API_EXAMPLES: {
68 TOUR_ID: 'tour-paris-explorer',
69 CUSTOMER_NAME: 'Jane Doe',
112} as const;
113
114// Define comprehensive request schema with .openapi() - NOT .meta()
115const CreateBookingRequestSchema = z.object({
116 tourId: z.string()
119 .regex(new RegExp(BOOKING_CREATE_CONSTANTS.PATTERNS.TOUR_ID))
120 .describe('Public tour identifier (slug form) from tour catalogue')
121 .openapi({
122 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TOUR_ID,
123 pattern: BOOKING_CREATE_CONSTANTS.PATTERNS.TOUR_ID,
124 minLength: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MIN_TOUR_ID_LENGTH,
130 .max(BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MAX_NAME_LENGTH)
131 .describe('Primary customer full name')
132 .openapi({
133 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.CUSTOMER_NAME,
134 minLength: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MIN_NAME_LENGTH,
135 maxLength: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MAX_NAME_LENGTH,
139 .max(BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MAX_EMAIL_LENGTH)
140 .describe('Customer contact email (honeypot emoji removed server-side)')
141 .openapi({
142 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.CUSTOMER_EMAIL,
143 format: 'email',
144 maxLength: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MAX_EMAIL_LENGTH,
147 .regex(new RegExp(BOOKING_CREATE_CONSTANTS.PATTERNS.DATE_YYYY_MM_DD))
148 .describe('Requested tour date (YYYY-MM-DD) must exist in tour\'s datesAvailable array')
149 .openapi({
150 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.BOOKING_DATE,
151 pattern: BOOKING_CREATE_CONSTANTS.PATTERNS.DATE_YYYY_MM_DD,
152 description: 'ISO calendar date, client should select from datesAvailable returned by tour listing',
157 .max(BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MAX_PEOPLE)
158 .describe('Number of participants included in booking')
159 .openapi({
160 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.NUMBER_OF_PEOPLE,
161 minimum: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MIN_PEOPLE,
162 maximum: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MAX_PEOPLE,
168 .optional()
169 .describe('Client-calculated payment amount override (major units); defaults to tour.price * numberOfPeople if omitted')
170 .openapi({
171 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.PAYMENT_AMOUNT,
172 minimum: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MIN_PAYMENT,
173 maximum: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MAX_PAYMENT,
177 .optional()
178 .describe('Optional free-form special requirements / notes')
179 .openapi({
180 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.SPECIAL_REQUESTS,
181 maxLength: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MAX_SPECIAL_REQUESTS_LENGTH,
182 }),
186 .optional()
187 .describe('Primary traveller given name')
188 .openapi({
189 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.FIRST_NAME,
190 maxLength: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MAX_FIRST_NAME_LENGTH,
191 }),
194 .optional()
195 .describe('Primary traveller family name')
196 .openapi({
197 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.LAST_NAME,
198 maxLength: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MAX_LAST_NAME_LENGTH,
199 }),
202 .optional()
203 .describe('Traveller contact email (may differ from booking contact)')
204 .openapi({
205 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TRAVELLER_EMAIL,
206 format: 'email',
207 }),
209 .optional()
210 .describe('Contact phone (E.164 recommended)')
211 .openapi({
212 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.PHONE_NUMBER,
213 }),
214 numberOfTravelers: z.number()
218 .optional()
219 .describe('Total travellers represented by travellerInfo (fallback to numberOfPeople)')
220 .openapi({
221 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.NUMBER_OF_PEOPLE,
222 minimum: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MIN_PEOPLE,
223 maximum: BOOKING_CREATE_CONSTANTS.VALIDATION_LIMITS.MAX_PEOPLE,
227 .optional()
228 .describe('Alternate preferred date (if primary unavailable)')
229 .openapi({
230 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.PREFERRED_DATE,
231 }),
232 dietaryRestrictions: z.string()
233 .optional()
234 .describe('Dietary needs summary')
235 .openapi({
236 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.DIETARY_RESTRICTIONS,
237 }),
238 emergencyContact: z.string()
239 .optional()
240 .describe('Emergency contact name')
241 .openapi({
242 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.EMERGENCY_CONTACT,
243 }),
244 emergencyPhone: z.string()
245 .optional()
246 .describe('Emergency contact phone')
247 .openapi({
248 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.EMERGENCY_PHONE,
249 }),
250 subscribeNewsletter: z.boolean()
251 .optional()
252 .describe('Whether customer opts into marketing updates')
253 .openapi({
254 example: true,
255 }),
257 .optional()
258 .describe('Acceptance of booking terms & conditions')
259 .openapi({
260 example: true,
261 }),
262 }).optional().describe('Optional extended traveller profile & preferences').openapi({
263 description: 'Nested attributes for more detailed traveller information',
264 example: {
265 firstName: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.FIRST_NAME,
266 lastName: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.LAST_NAME,
267 email: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TRAVELLER_EMAIL,
268 phoneNumber: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.PHONE_NUMBER,
269 numberOfTravelers: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.NUMBER_OF_PEOPLE,
270 dietaryRestrictions: '1x vegetarian',
271 subscribeNewsletter: true,
273 },
274 }),
275}).openapi('CreateBookingRequest');
276
277// Define comprehensive booking data schema
280 .regex(new RegExp(BOOKING_CREATE_CONSTANTS.PATTERNS.UUID_V4))
281 .describe('Booking unique identifier (UUID v4)')
282 .openapi({
283 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.BOOKING_ID,
284 format: 'uuid',
285 pattern: BOOKING_CREATE_CONSTANTS.PATTERNS.UUID_V4,
287 tourId: z.string()
288 .describe('Tour slug identifier')
289 .openapi({
290 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TOUR_ID,
291 }),
292 title: z.string()
293 .describe('Booking title combining tour + customer')
294 .openapi({
295 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.BOOKING_TITLE,
296 }),
297 description: z.string()
298 .describe('Human readable booking summary')
299 .openapi({
300 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.BOOKING_DESCRIPTION,
301 }),
302 paymentAmount: z.number()
303 .positive()
304 .describe('Per-person or total payment amount recorded')
305 .openapi({
306 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TOUR_PRICE,
307 minimum: 0.01,
308 }),
309 customerName: z.string()
310 .describe('Primary customer name')
311 .openapi({
312 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.CUSTOMER_NAME,
313 }),
314 customerEmail: z.string()
315 .email()
316 .describe('Primary contact email')
317 .openapi({
318 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.CUSTOMER_EMAIL,
319 format: 'email',
320 }),
321 bookingDate: z.string()
322 .describe('Selected tour date (YYYY-MM-DD)')
323 .openapi({
324 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.BOOKING_DATE,
325 }),
326 numberOfPeople: z.number()
328 .positive()
329 .describe('Number of participants')
330 .openapi({
331 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.NUMBER_OF_PEOPLE,
332 minimum: 1,
333 format: 'int32',
336 .positive()
337 .describe('Total computed amount (paymentAmount * numberOfPeople)')
338 .openapi({
339 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TOTAL_AMOUNT,
340 minimum: 0.01,
341 }),
342 status: z.enum(['pending', 'confirmed', 'cancelled', 'completed'])
343 .describe('Booking status lifecycle')
344 .openapi({
345 example: BOOKING_CREATE_CONSTANTS.BOOKING_STATUSES.PENDING,
346 enum: ['pending', 'confirmed', 'cancelled', 'completed'],
348 paymentStatus: z.enum(['pending', 'paid', 'refunded', 'cancelled'])
349 .describe('Payment settlement status')
350 .openapi({
351 example: BOOKING_CREATE_CONSTANTS.PAYMENT_STATUSES.PENDING,
352 enum: ['pending', 'paid', 'refunded', 'cancelled'],
355 .optional()
356 .describe('Special requests text')
357 .openapi({
358 example: 'Wheelchair access required',
359 }),
361 .optional()
362 .describe('Traveller given name')
363 .openapi({
364 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.FIRST_NAME,
365 }),
366 lastName: z.string()
367 .optional()
368 .describe('Traveller family name')
369 .openapi({
370 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.LAST_NAME,
371 }),
372 email: z.string()
374 .optional()
375 .describe('Traveller email')
376 .openapi({
377 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TRAVELLER_EMAIL,
378 format: 'email',
379 }),
381 .optional()
382 .describe('Contact phone')
383 .openapi({
384 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.PHONE_NUMBER,
385 }),
386 numberOfTravelers: z.number()
389 .optional()
390 .describe('Traveller count override')
391 .openapi({
392 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.NUMBER_OF_PEOPLE,
393 minimum: 1,
394 format: 'int32',
397 .optional()
398 .describe('Alternate preferred date')
399 .openapi({
400 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.PREFERRED_DATE,
401 }),
402 dietaryRestrictions: z.string()
403 .optional()
404 .describe('Dietary requirements summary')
405 .openapi({
406 example: '1x vegetarian',
407 }),
409 .optional()
410 .describe('Emergency contact name')
411 .openapi({
412 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.EMERGENCY_CONTACT,
413 }),
414 emergencyPhone: z.string()
415 .optional()
416 .describe('Emergency contact phone')
417 .openapi({
418 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.EMERGENCY_PHONE,
419 }),
420 subscribeNewsletter: z.number()
424 .optional()
425 .describe('Newsletter opt-in stored as tinyint (1=yes,0=no)')
426 .openapi({
427 example: 1,
428 minimum: 0,
436 .optional()
437 .describe('Terms acceptance flag stored as tinyint')
438 .openapi({
439 example: 1,
440 minimum: 0,
446 .nullable()
447 .describe('Session identifier associated with booking creation')
448 .openapi({
449 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.SESSION_ID,
450 format: 'uuid',
451 pattern: BOOKING_CREATE_CONSTANTS.PATTERNS.UUID_V4,
454 .regex(new RegExp(BOOKING_CREATE_CONSTANTS.PATTERNS.ISO_DATETIME))
455 .describe('Creation timestamp ISO 8601')
456 .openapi({
457 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.CREATED_AT,
458 format: 'date-time',
459 pattern: BOOKING_CREATE_CONSTANTS.PATTERNS.ISO_DATETIME,
462 .regex(new RegExp(BOOKING_CREATE_CONSTANTS.PATTERNS.ISO_DATETIME))
463 .describe('Last update timestamp ISO 8601')
464 .openapi({
465 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.UPDATED_AT,
466 format: 'date-time',
467 pattern: BOOKING_CREATE_CONSTANTS.PATTERNS.ISO_DATETIME,
468 }),
469}).openapi('BookingData');
470
471// Define response schemas
473 success: z.literal(true)
474 .describe('Indicates booking creation succeeded')
475 .openapi({
476 example: true,
477 }),
480 'payment-init': z.string()
481 .describe('Nonce for initiating payment flow')
482 .openapi({
483 example: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.PAYMENT_INIT_NONCE,
484 }),
485 }).describe('Fresh page nonces for follow-up privileged actions'),
486}).openapi('CreateBookingResponse');
487
488const BookingErrorSchema = z.object({
489 success: z.literal(false),
490 error: z.string().openapi({
491 example: BOOKING_CREATE_CONSTANTS.ERROR_MESSAGES.BOOKING_CREATION_FAILED,
492 description: 'Error message describing the booking creation failure'
493 }),
494}).openapi('BookingError');
495
496// Create booking route
497export const createBookingRoute = createRoute({
498 method: 'post',
499 path: '/api/v1/booking',
500 tags: ['Bookings', 'Payments'],
501 summary: 'Create Booking',
525### Usage Example
526\`\`\`bash
527curl -X POST "https://api.example.com/api/v1/booking" \\
528 -H "Content-Type: application/json" \\
529 -H "X-JWT-CSRF-Token: <jwt_csrf_token>" \\
597 booking: {
598 value: {
599 tourId: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TOUR_ID,
600 customerName: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.CUSTOMER_NAME,
601 customerEmail: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.CUSTOMER_EMAIL,
602 bookingDate: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.BOOKING_DATE,
603 numberOfPeople: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.NUMBER_OF_PEOPLE,
604 travellerInfo: {
605 firstName: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.FIRST_NAME,
606 lastName: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.LAST_NAME,
607 acceptTerms: true,
608 },
625 success: true,
626 data: {
627 id: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.BOOKING_ID,
628 tourId: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TOUR_ID,
629 title: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.BOOKING_TITLE,
630 description: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.BOOKING_DESCRIPTION,
631 paymentAmount: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TOUR_PRICE,
632 customerName: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.CUSTOMER_NAME,
633 customerEmail: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.CUSTOMER_EMAIL,
634 bookingDate: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.BOOKING_DATE,
635 numberOfPeople: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.NUMBER_OF_PEOPLE,
636 totalAmount: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TOTAL_AMOUNT,
637 status: BOOKING_CREATE_CONSTANTS.BOOKING_STATUSES.PENDING,
638 paymentStatus: BOOKING_CREATE_CONSTANTS.PAYMENT_STATUSES.PENDING,
639 sessionId: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.SESSION_ID,
640 createdAt: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.CREATED_AT,
641 updatedAt: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.UPDATED_AT,
642 },
643 pageNonces: {
644 'payment-init': BOOKING_CREATE_CONSTANTS.API_EXAMPLES.PAYMENT_INIT_NONCE,
645 },
646 },
671 * @example
672 * ```typescript
673 * app.openapi(createBookingRoute, createBookingHandler);
674 * ```
675 * @since 1.0.0
680 // Mock request data parsing for testing purposes
681 const mockRequestData = {
682 tourId: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TOUR_ID,
683 customerName: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.CUSTOMER_NAME,
684 customerEmail: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.CUSTOMER_EMAIL,
685 bookingDate: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.BOOKING_DATE,
686 numberOfPeople: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.NUMBER_OF_PEOPLE,
687 travellerInfo: {
688 firstName: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.FIRST_NAME,
689 lastName: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.LAST_NAME,
690 acceptTerms: true,
691 },
705 // Mock tour lookup and pricing calculation for testing purposes
706 const mockTour = {
707 tourId: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TOUR_ID,
708 title: 'Paris Explorer ๐Ÿ—ผ',
709 price: BOOKING_CREATE_CONSTANTS.API_EXAMPLES.TOUR_PRICE,
710 };
711
721 // PLACEHOLDER: In real app, this would generate secure UUIDs and manage sessions
722 // Mock UUID generation and session management for testing purposes
723 const bookingId = BOOKING_CREATE_CONSTANTS.API_EXAMPLES.BOOKING_ID;
724 const sessionId = BOOKING_CREATE_CONSTANTS.API_EXAMPLES.SESSION_ID;
725
726 // PLACEHOLDER: In real app, this would create the booking record in database
754 // PLACEHOLDER: In real app, this would generate fresh page nonces
755 // Mock nonce generation for testing purposes
756 const paymentInitNonce = BOOKING_CREATE_CONSTANTS.API_EXAMPLES.PAYMENT_INIT_NONCE;
757 const pageNoncesPayload = {
758 [BOOKING_CREATE_CONSTANTS.NONCE_TYPES.PAYMENT_INIT]: paymentInitNonce,

ZenAPIServer_auth.turnstileVerify.ts.bak29 matches

@ianmenethilโ€ขUpdated 2 weeks ago
3 *
4 * Verifies Cloudflare Turnstile response tokens to prevent automated interactions
5 * Following EXACTLY the hono-zod-openapi-correct-usage.md patterns
6 *
7 * ## Component Category
21 */
22
23import { createRoute, z, type RouteHandler } from 'npm:@hono/zod-openapi';
24import type { AppEnv } from '../types/index.ts';
25
52 INTERNAL_ERROR: 'Internal verification error',
53 },
54 API_EXAMPLES: {
55 TOKEN: '0x4AAAAAAAC2mU1rG7x2q8x1d8P5w3c9L7hK1y_mQshpXz8y1g4nS9XoXxH0bSgX6A',
56 CHALLENGE_TS: '2025-08-16T10:22:41.512Z',
61} as const;
62
63// Define request schema with .openapi() - NOT .meta()
64const TurnstileVerifyRequestSchema = z.object({
65 token: z.string()
68 .regex(new RegExp(TURNSTILE_VERIFY_CONSTANTS.PATTERNS.TOKEN_PATTERN))
69 .describe('Turnstile response token')
70 .openapi({
71 description: 'The client-side Turnstile response token obtained after the user passes the challenge',
72 example: TURNSTILE_VERIFY_CONSTANTS.API_EXAMPLES.TOKEN,
73 minLength: TURNSTILE_VERIFY_CONSTANTS.VALIDATION_LIMITS.MIN_TOKEN_LENGTH,
74 maxLength: TURNSTILE_VERIFY_CONSTANTS.VALIDATION_LIMITS.MAX_TOKEN_LENGTH,
75 pattern: TURNSTILE_VERIFY_CONSTANTS.PATTERNS.TOKEN_PATTERN,
76 }),
77}).openapi('TurnstileVerifyRequest');
78
79// Define success response schema with .openapi() - NOT .meta()
80const TurnstileVerifySuccessSchema = z.object({
81 valid: z.boolean()
82 .describe('Token validation result')
83 .openapi({
84 description: 'Indicates if token verification succeeded',
85 example: true,
89 .optional()
90 .describe('Challenge timestamp')
91 .openapi({
92 description: 'ISO 8601 timestamp when the original challenge was solved (server-generated surrogate)',
93 example: TURNSTILE_VERIFY_CONSTANTS.API_EXAMPLES.CHALLENGE_TS,
94 format: 'date-time',
95 pattern: TURNSTILE_VERIFY_CONSTANTS.PATTERNS.DATETIME_ISO,
99 .optional()
100 .describe('Associated hostname')
101 .openapi({
102 description: 'Expected hostname associated with the sitekey (if available)',
103 example: TURNSTILE_VERIFY_CONSTANTS.API_EXAMPLES.HOSTNAME,
104 pattern: TURNSTILE_VERIFY_CONSTANTS.PATTERNS.HOSTNAME_PATTERN,
105 }),
106}).openapi('TurnstileVerifySuccess');
107
108const TurnstileVerifyErrorSchema = z.object({
109 valid: z.literal(false)
110 .describe('Validation failed')
111 .openapi({
112 description: 'Always false when validation fails',
113 example: false,
118 .max(TURNSTILE_VERIFY_CONSTANTS.VALIDATION_LIMITS.MAX_ERROR_MESSAGE_LENGTH)
119 .describe('Error description')
120 .openapi({
121 description: 'Error description when validation fails',
122 example: TURNSTILE_VERIFY_CONSTANTS.API_EXAMPLES.ERROR_INVALID,
123 minLength: TURNSTILE_VERIFY_CONSTANTS.VALIDATION_LIMITS.MIN_ERROR_MESSAGE_LENGTH,
124 maxLength: TURNSTILE_VERIFY_CONSTANTS.VALIDATION_LIMITS.MAX_ERROR_MESSAGE_LENGTH,
125 }),
126}).openapi('TurnstileVerifyError');
127
128// Create route with ALL possible response status codes
129export const route = createRoute({
130 method: 'post',
131 path: '/api/v1/auth/turnstile-verify',
132 tags: ['Authentication', 'Security'],
133 summary: 'Verify Turnstile Token',
152### Usage Example
153\`\`\`bash
154curl -X POST "https://api.example.com/api/v1/auth/turnstile-verify" \\
155 -H "Content-Type: application/json" \\
156 -d '{"token":"0x4AAAAAAAC2mU1rG7x2q8x1d8P5w3c9L7hK1y_mQshpXz8y1g4nS9XoXxH0bSgX6A"}'
206 value: {
207 valid: true,
208 challengeTs: TURNSTILE_VERIFY_CONSTANTS.API_EXAMPLES.CHALLENGE_TS,
209 hostname: TURNSTILE_VERIFY_CONSTANTS.API_EXAMPLES.HOSTNAME,
210 },
211 },
223 value: {
224 valid: false,
225 error: TURNSTILE_VERIFY_CONSTANTS.API_EXAMPLES.ERROR_INVALID,
226 },
227 },
229 value: {
230 valid: false,
231 error: TURNSTILE_VERIFY_CONSTANTS.API_EXAMPLES.ERROR_TIMEOUT,
232 },
233 },
258 * @example
259 * ```typescript
260 * app.openapi(route, handler);
261 * ```
262 * @since 1.0.0
268 const { token } = TurnstileVerifyRequestSchema.parse(requestBody);
269
270 // PLACEHOLDER: Mock token validation (in real app: call Cloudflare API)
271 if (!token || typeof token !== 'string') {
272 return c.json({
281 return c.json({
282 valid: false as const,
283 error: TURNSTILE_VERIFY_CONSTANTS.API_EXAMPLES.ERROR_INVALID
284 }, TURNSTILE_VERIFY_CONSTANTS.HTTP_STATUS.UNPROCESSABLE_ENTITY);
285 }
288 return c.json({
289 valid: false as const,
290 error: TURNSTILE_VERIFY_CONSTANTS.API_EXAMPLES.ERROR_TIMEOUT
291 }, TURNSTILE_VERIFY_CONSTANTS.HTTP_STATUS.UNPROCESSABLE_ENTITY);
292 }
296 valid: true as const,
297 challengeTs: new Date().toISOString(),
298 hostname: TURNSTILE_VERIFY_CONSTANTS.API_EXAMPLES.HOSTNAME,
299 };
300

ZenAPIServer_auth.tokens.ts.bak24 matches

@ianmenethilโ€ขUpdated 2 weeks ago
3 *
4 * Provides JWT-CSRF tokens and session establishment
5 * Following EXACTLY the hono-zod-openapi-correct-usage.md patterns
6 *
7 * ## Component Category
20 */
21
22import { createRoute, z, type RouteHandler } from 'npm:@hono/zod-openapi';
23import type { AppEnv } from '../types/index.ts';
24
58 HONEYPOT_EMOJI: 'honeypotEmoji',
59 },
60 API_VERSION: '1.0.0',
61} as const;
62
63// Define response schema with .openapi() - NOT .meta()
64const AuthTokensResponseSchema = z.object({
65 type: z.enum(['bootstrap', 'refresh'])
66 .describe('Token operation type')
67 .openapi({
68 description: 'Type of token operation being performed',
69 example: 'bootstrap',
73 token: z.string()
74 .describe('JWT-CSRF token')
75 .openapi({
76 description: 'Secure JWT-CSRF token for authentication',
77 example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uSWQiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMCIsImNzcmZJZCI6IjU1MGU4NDAwLWUyOWItNDFkNC1hNzE2LTQ0NjY1NTQ0MDAwIiwiaWF0IjoxNzM2OTk5ODAwLCJleHAiOjE3MzY5OTk4NjB9.signature',
84 headerName: z.string()
85 .describe('Header name for token submission')
86 .openapi({
87 description: 'HTTP header name to use when submitting the token',
88 example: 'X-JWT-CSRF-Token',
94 .positive()
95 .describe('Token expiration time in seconds')
96 .openapi({
97 description: 'Token expiration time in seconds from now',
98 example: 3600,
105 .describe('Page-specific nonces for action authorization')
106 .optional()
107 .openapi({
108 description: 'Nonces for specific page actions (booking submit, payment init)',
109 example: {
119 sessionEstablished: z.boolean()
120 .describe('Whether session was created')
121 .openapi({
122 description: 'Indicates if a new session was successfully established',
123 example: true,
128 .describe('Session identifier')
129 .optional()
130 .openapi({
131 description: 'Unique session identifier for tracking',
132 example: '550e8400-e29b-41d4-a716-446655440000',
138 .describe('CSRF correlation identifier')
139 .optional()
140 .openapi({
141 description: 'Opaque UUID linking JWT to CSRF/session context for double-submit mitigation',
142 example: '8f5a4d1c-9e32-4f6a-9b75-1d2c3e4f5a6b',
146 honeypotEmoji: z.string()
147 .describe('Dynamic emoji for honeypot security')
148 .openapi({
149 description: 'Random emoji used for bot detection and security validation',
150 example: '๐Ÿฆ„',
157 .describe('Timestamp when tokens were generated')
158 .optional()
159 .openapi({
160 description: 'ISO 8601 timestamp of token generation',
161 example: '2024-01-15T10:30:00Z',
164
165 version: z.string()
166 .describe('API version')
167 .optional()
168 .openapi({
169 description: 'API version identifier',
170 example: '1.0.0',
171 pattern: AUTH_TOKENS_CONSTANTS.PATTERNS.VERSION_PATTERN,
172 }),
173}).openapi('AuthTokensResponse');
174
175const ErrorSchema = z.object({
176 success: z.literal(false),
177 error: z.string().openapi({
178 example: 'Token generation failed',
179 description: 'Error message'
180 }),
181}).openapi('AuthTokensError');
182
183// Create route with ALL possible response status codes
184export const route = createRoute({
185 method: 'get',
186 path: '/api/v1/auth/tokens',
187 tags: ['Authentication', 'Security'],
188 summary: 'Get Authentication Tokens',
211### Usage Example
212\`\`\`bash
213curl -X GET "https://api.example.com/api/v1/auth/tokens" \\
214 -H "Accept: application/json" \\
215 -H "User-Agent: YourApp/1.0"
311 * @example
312 * ```typescript
313 * app.openapi(route, handler);
314 * ```
315 * @since 1.0.0
350 honeypotEmoji,
351 generatedAt: new Date().toISOString(),
352 version: AUTH_TOKENS_CONSTANTS.API_VERSION,
353 csrfId,
354 }, AUTH_TOKENS_CONSTANTS.HTTP_STATUS.OK);

todoist-api

@scottscharlโ€ขUpdated 17 hours ago

elevenLabsDialogueTester2 file matches

@dcm31โ€ขUpdated 1 day ago
Public tester for ElevenLabs text-to-dialogue API
fapian
<("<) <(")> (>")>
Kapil01