Add server infrastructure with API routes and middleware
- Create API route structure (auth, health, internal) - Add authentication middleware for internal pages - Add database connection utilities - Implement health check endpoint
This commit is contained in:
53
server/middleware/internal-auth.ts
Normal file
53
server/middleware/internal-auth.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Basic Authentication Middleware for /internal/* routes
|
||||
* Protects internal pages (styleguide, admin tools) with HTTP Basic Auth
|
||||
*/
|
||||
|
||||
export default defineEventHandler((event) => {
|
||||
const path = event.path
|
||||
|
||||
// Only protect /internal/* routes
|
||||
if (!path.startsWith('/internal')) {
|
||||
return
|
||||
}
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
// Get credentials from environment variables
|
||||
const validUsername = config.internalAuthUsername
|
||||
const validPassword = config.internalAuthPassword
|
||||
|
||||
// Skip auth if credentials are not configured (development convenience)
|
||||
if (!validUsername || !validPassword) {
|
||||
console.warn('⚠️ INTERNAL_AUTH_USERNAME or INTERNAL_AUTH_PASSWORD not set. /internal routes are unprotected!')
|
||||
return
|
||||
}
|
||||
|
||||
// Get Authorization header
|
||||
const authHeader = getHeader(event, 'authorization')
|
||||
|
||||
if (!authHeader || !authHeader.startsWith('Basic ')) {
|
||||
// Request authentication
|
||||
setHeader(event, 'WWW-Authenticate', 'Basic realm="Internal Area"')
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
statusMessage: 'Authentication required',
|
||||
})
|
||||
}
|
||||
|
||||
// Decode credentials
|
||||
const base64Credentials = authHeader.split(' ')[1]
|
||||
const credentials = Buffer.from(base64Credentials, 'base64').toString('utf-8')
|
||||
const [username, password] = credentials.split(':')
|
||||
|
||||
// Validate credentials
|
||||
if (username !== validUsername || password !== validPassword) {
|
||||
setHeader(event, 'WWW-Authenticate', 'Basic realm="Internal Area"')
|
||||
throw createError({
|
||||
statusCode: 401,
|
||||
statusMessage: 'Invalid credentials',
|
||||
})
|
||||
}
|
||||
|
||||
// Authentication successful, continue
|
||||
})
|
||||
34
server/utils/db.ts
Normal file
34
server/utils/db.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { drizzle } from 'drizzle-orm/postgres-js'
|
||||
import postgres from 'postgres'
|
||||
import * as schema from '../database/schema'
|
||||
|
||||
/**
|
||||
* Database connection utility
|
||||
*
|
||||
* Creates a singleton Drizzle ORM instance with the complete schema.
|
||||
* This allows for type-safe database queries throughout the application.
|
||||
*
|
||||
* Usage:
|
||||
* ```typescript
|
||||
* import { db } from '~/server/utils/db'
|
||||
*
|
||||
* // Query with relations
|
||||
* const users = await db.query.users.findMany({
|
||||
* with: { orders: true }
|
||||
* })
|
||||
*
|
||||
* // Raw SQL with type safety
|
||||
* import { users } from '~/server/database/schema'
|
||||
* import { eq } from 'drizzle-orm'
|
||||
*
|
||||
* const user = await db.select().from(users).where(eq(users.id, userId))
|
||||
* ```
|
||||
*/
|
||||
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
// Create postgres.js client
|
||||
const client = postgres(config.databaseUrl)
|
||||
|
||||
// Create Drizzle ORM instance with schema
|
||||
export const db = drizzle(client, { schema })
|
||||
Reference in New Issue
Block a user