Initial commit — Performance West telecom compliance platform

Includes: API (Express/TypeScript), Astro site, Python workers,
document generators, FCC compliance tools, Canada CRTC formation,
Ansible infrastructure, and deployment scripts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
justin 2026-04-27 06:54:22 -05:00
commit f8cd37ac8c
1823 changed files with 145167 additions and 0 deletions

View file

@ -0,0 +1,30 @@
import type { Request, Response, NextFunction } from "express";
/**
* Structured access logger. Outputs one JSON line per request to stdout
* prefixed with [ACCESS] for easy parsing by fail2ban and log aggregation.
*/
export function accessLog(req: Request, res: Response, next: NextFunction): void {
const start = Date.now();
res.on("finish", () => {
const ms = Date.now() - start;
const log = {
ts: new Date().toISOString(),
ip: (req as any).clientIp || req.ip || "-",
method: req.method,
path: req.originalUrl,
status: res.statusCode,
ms,
ua: req.headers["user-agent"]?.slice(0, 200) || "-",
bytes: parseInt(res.getHeader("content-length") as string, 10) || 0,
};
// Only log non-health requests (reduces noise)
if (req.originalUrl !== "/api/v1/status") {
console.log(`[ACCESS] ${JSON.stringify(log)}`);
}
});
next();
}

View file

@ -0,0 +1,41 @@
import type { Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";
import { config } from "../config.js";
const JWT_SECRET = process.env.ADMIN_JWT_SECRET || "change-this-in-production";
export interface AdminPayload {
id: number;
username: string;
}
declare global {
namespace Express {
interface Request {
admin?: AdminPayload;
}
}
}
/** Sign a JWT for an admin user. */
export function signAdminToken(payload: AdminPayload): string {
return jwt.sign(payload, JWT_SECRET, { expiresIn: "8h" });
}
/** Verify admin JWT from Authorization: Bearer <token> header. */
export function requireAdmin(req: Request, res: Response, next: NextFunction): void {
const header = req.headers.authorization;
if (!header || !header.startsWith("Bearer ")) {
res.status(401).json({ error: "Authentication required." });
return;
}
const token = header.slice(7);
try {
const decoded = jwt.verify(token, JWT_SECRET) as AdminPayload;
req.admin = decoded;
next();
} catch {
res.status(401).json({ error: "Invalid or expired token." });
}
}

View file

@ -0,0 +1,41 @@
import cors from "cors";
import { config } from "../config.js";
const PRODUCTION_ORIGINS = [
"https://performancewest.net",
"https://www.performancewest.net",
"https://dev.performancewest.net",
"http://192.168.7.4:4322",
];
const DEV_ORIGINS = [
"http://localhost:4322",
"http://localhost:3001",
"http://127.0.0.1:4322",
"http://127.0.0.1:3001",
];
// In dev mode, also allow any origin on common dev ports (LAN access)
const isDev = config.nodeEnv !== "production";
const allowedOrigins =
config.nodeEnv === "production"
? PRODUCTION_ORIGINS
: [...PRODUCTION_ORIGINS, ...DEV_ORIGINS];
export const corsMiddleware = cors({
origin: (origin, cb) => {
// Allow requests with no origin (server-to-server, curl, etc.)
if (!origin) { cb(null, true); return; }
if (allowedOrigins.includes(origin)) { cb(null, true); return; }
// In dev mode, allow any origin on known dev ports (LAN access from other machines)
if (isDev && /^http:\/\/[\d.]+:(4322|3001)$/.test(origin)) { cb(null, true); return; }
if (isDev && /^http:\/\/192\.168\./.test(origin)) { cb(null, true); return; }
cb(new Error(`Origin ${origin} not allowed by CORS`));
},
methods: ["GET", "POST", "PATCH", "OPTIONS"],
allowedHeaders: ["Content-Type", "Authorization"],
exposedHeaders: ["RateLimit-Limit", "RateLimit-Remaining", "RateLimit-Reset"],
credentials: true,
maxAge: 86_400,
});

View file

@ -0,0 +1,57 @@
import { Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";
const JWT_SECRET = process.env.ADMIN_JWT_SECRET || "changeme";
const COOKIE_NAME = "pw_customer";
export interface CustomerPayload {
customerId: number;
email: string;
}
declare global {
namespace Express {
interface Request {
customer?: CustomerPayload;
}
}
}
/** Middleware: attach customer from cookie JWT. Never blocks — sets req.customer if valid. */
export function optionalCustomerAuth(req: Request, _res: Response, next: NextFunction) {
const token = req.cookies?.[COOKIE_NAME];
if (!token) return next();
try {
req.customer = jwt.verify(token, JWT_SECRET) as CustomerPayload;
} catch {
// expired or invalid — ignore, let route decide
}
next();
}
/** Middleware: require valid customer session. Returns 401 if not logged in. */
export function requireCustomerAuth(req: Request, res: Response, next: NextFunction) {
optionalCustomerAuth(req, res, () => {
if (!req.customer) {
return res.status(401).json({ error: "Login required", code: "UNAUTHENTICATED" });
}
next();
});
}
/** Issue a customer session JWT cookie (7-day). */
export function issueCustomerCookie(res: Response, payload: CustomerPayload) {
const token = jwt.sign(payload, JWT_SECRET, { expiresIn: "7d" });
res.cookie(COOKIE_NAME, token, {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "lax",
maxAge: 7 * 24 * 60 * 60 * 1000,
path: "/",
});
}
/** Clear the customer session cookie. */
export function clearCustomerCookie(res: Response) {
res.clearCookie(COOKIE_NAME, { path: "/" });
}

View file

@ -0,0 +1,33 @@
import type { Request, Response, NextFunction } from "express";
interface AppError extends Error {
statusCode?: number;
details?: unknown;
}
/** Create a typed error with status code. */
export function createError(message: string, statusCode: number, details?: unknown): AppError {
const err: AppError = new Error(message);
err.statusCode = statusCode;
err.details = details;
return err;
}
/** Express error-handling middleware — must be mounted last. */
export function errorHandler(
err: AppError,
_req: Request,
res: Response,
_next: NextFunction,
): void {
const status = err.statusCode || 500;
const isDev = process.env.NODE_ENV !== "production";
console.error(`[ERROR] ${status} ${err.message}`, isDev ? err.stack : "");
res.status(status).json({
error: err.message || "Internal server error",
...(err.details ? { details: err.details } : {}),
...(isDev && err.stack ? { stack: err.stack } : {}),
});
}

View file

@ -0,0 +1,27 @@
// internal-auth.ts — Shared-secret authentication for internal API endpoints
// Used by Verilex Data to access bulk entity export and name search endpoints.
import type { Request, Response, NextFunction } from "express";
const INTERNAL_API_KEY = process.env.PW_INTERNAL_API_KEY || "";
export function internalAuth(req: Request, res: Response, next: NextFunction): void {
if (!INTERNAL_API_KEY) {
res.status(503).json({ error: "Internal API not configured" });
return;
}
const authHeader = req.headers.authorization || "";
if (!authHeader.startsWith("Bearer ")) {
res.status(401).json({ error: "Missing Authorization header" });
return;
}
const token = authHeader.slice(7);
if (token !== INTERNAL_API_KEY) {
res.status(401).json({ error: "Invalid API key" });
return;
}
next();
}

View file

@ -0,0 +1,107 @@
/**
* Portal authentication middleware.
*
* Customer portal pages (/portal/*) are accessed via signed JWT links that
* are emailed to customers. No password is needed the link IS the credential.
*
* Token format (JWT, HS256):
* payload: { order_id, order_type, email, iat, exp }
* secret: CUSTOMER_JWT_SECRET env var
*
* Token is passed as:
* 1. Query param: ?token=... (email links)
* 2. Authorization header: Bearer ... (XHR/fetch from portal page)
* 3. Cookie: pw_portal_token=... (set by the portal page on first load)
*
* Helper: generatePortalToken(order_id, order_type, email) signed JWT
*/
import { type Request, type Response, type NextFunction } from "express";
import jwt from "jsonwebtoken";
const CUSTOMER_JWT_SECRET = process.env.CUSTOMER_JWT_SECRET || "changeme_long_random_string";
const TOKEN_TTL_SECONDS = 72 * 60 * 60; // 72 hours
export interface PortalTokenPayload {
order_id: string;
order_type: string;
email: string;
}
// ─── Generate a signed portal link token ─────────────────────────────────────
export function generatePortalToken(
order_id: string,
order_type: string,
email: string,
): string {
return jwt.sign(
{ order_id, order_type, email } satisfies PortalTokenPayload,
CUSTOMER_JWT_SECRET,
{ expiresIn: TOKEN_TTL_SECONDS },
);
}
// ─── Build a signed portal URL ────────────────────────────────────────────────
export function portalUrl(
path: string, // e.g. "/portal/domain-search"
order_id: string,
order_type: string,
email: string,
): string {
const token = generatePortalToken(order_id, order_type, email);
const domain = process.env.DOMAIN ? `https://${process.env.DOMAIN}` : "http://localhost:4321";
return `${domain}${path}?token=${encodeURIComponent(token)}`;
}
// ─── Middleware: verify portal token ─────────────────────────────────────────
// Attaches req.portalAuth = { order_id, order_type, email } on success.
// Returns 401 if token is missing, 403 if invalid/expired.
declare global {
namespace Express {
interface Request {
portalAuth?: PortalTokenPayload;
}
}
}
export function requirePortalAuth(req: Request, res: Response, next: NextFunction): void {
// 1. Query param (email link on first load)
let rawToken = (req.query.token as string) || null;
// 2. Authorization header (XHR from portal page after first load)
if (!rawToken) {
const authHeader = req.headers.authorization || "";
if (authHeader.startsWith("Bearer ")) {
rawToken = authHeader.slice(7);
}
}
// 3. Cookie (set by portal page JS after extracting from URL)
if (!rawToken) {
rawToken = (req.cookies?.pw_portal_token as string) || null;
}
if (!rawToken) {
res.status(401).json({ error: "Authentication required. Please use the link from your email.", code: "AUTH_REQUIRED" });
return;
}
try {
const payload = jwt.verify(rawToken, CUSTOMER_JWT_SECRET) as PortalTokenPayload & { iat: number; exp: number };
req.portalAuth = {
order_id: payload.order_id,
order_type: payload.order_type,
email: payload.email,
};
next();
} catch (err: any) {
if (err?.name === "TokenExpiredError") {
res.status(403).json({ error: "Your portal link has expired. Please request a new one.", code: "TOKEN_EXPIRED" });
} else {
res.status(403).json({ error: "Invalid portal link.", code: "TOKEN_INVALID" });
}
}
}

View file

@ -0,0 +1,21 @@
import rateLimit from "express-rate-limit";
/** Global rate limiter — 200 requests per minute per IP. */
export const globalLimiter = rateLimit({
windowMs: 60_000,
max: 200,
standardHeaders: true,
legacyHeaders: false,
keyGenerator: (req) => (req as any).clientIp || req.ip || "unknown",
message: { error: "Too many requests. Please wait and try again." },
});
/** Strict limiter for form submissions — 5 per minute per IP (50 in dev/test). */
export const submitLimiter = rateLimit({
windowMs: 60_000,
max: process.env.NODE_ENV === "production" ? 5 : 50,
standardHeaders: true,
legacyHeaders: false,
keyGenerator: (req) => (req as any).clientIp || req.ip || "unknown",
message: { error: "Too many submissions. Please wait a moment." },
});

View file

@ -0,0 +1,38 @@
import helmet from "helmet";
import type { Request, Response, NextFunction } from "express";
// Strict security headers via Helmet.
export const securityHeaders = helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'none'"],
frameAncestors: ["'none'"],
},
},
hsts: { maxAge: 31_536_000, includeSubDomains: true, preload: true },
frameguard: { action: "deny" },
noSniff: true,
referrerPolicy: { policy: "no-referrer" },
hidePoweredBy: true,
// This is a public API accessed cross-origin — must be cross-origin not same-origin
crossOriginResourcePolicy: { policy: "cross-origin" },
// Allow cross-origin opener for Stripe Identity redirect flows
crossOriginOpenerPolicy: { policy: "unsafe-none" },
});
// Attach normalised client IP to req (handles IPv6-mapped IPv4).
declare global {
namespace Express {
interface Request {
clientIp?: string;
}
}
}
export function extractClientIp(req: Request, _res: Response, next: NextFunction): void {
let ip = (req.headers["x-forwarded-for"] as string)?.split(",")[0]?.trim() || req.ip || "";
// Normalise ::ffff:127.0.0.1 → 127.0.0.1
if (ip.startsWith("::ffff:")) ip = ip.slice(7);
req.clientIp = ip;
next();
}