import { z } from 'zod';
export const createUserSchema = z
.object({
email: z.string().email(),
name: z.string().min(1).max(120),
-- KEYS[1] = bucket key
-- ARGV: capacity, refillPerSec, now(ms), cost, ttl(sec)
local capacity = tonumber(ARGV[1])
local refill = tonumber(ARGV[2])
local now = tonumber(ARGV[3])
local cost = tonumber(ARGV[4])
const MAX_LIMIT = 100;
const DEFAULT_LIMIT = 20;
const ALLOWED_ORDER = new Set(['asc', 'desc']);
function decodeCursor(raw) {
const json = Buffer.from(raw, 'base64').toString('utf8');
import jwt, { JwtPayload, SignOptions } from 'jsonwebtoken';
const SECRET = process.env.JWT_SECRET as string;
const ISSUER = 'auth.example.com';
const AUDIENCE = 'api.example.com';
const multer = require('multer');
const ALLOWED_MIME = new Set(['image/jpeg', 'image/png', 'image/webp']);
function fileFilter(req, file, cb) {
if (!ALLOWED_MIME.has(file.mimetype)) {
const withTimeout = (promise, timeoutMs, name) => {
let timer;
const timeout = new Promise((_, reject) => {
timer = setTimeout(
() => reject(new Error(`check '${name}' timed out after ${timeoutMs}ms`)),
timeoutMs
function encodeCursor(row) {
if (!row) return null;
const payload = JSON.stringify({ t: row.created_at, id: row.id });
return Buffer.from(payload, 'utf8').toString('base64url');
}
class ApiError extends Error {
constructor(statusCode, message, code) {
super(message);
this.name = 'ApiError';
this.statusCode = statusCode;
this.code = code || null;
const crypto = require('crypto');
function computeStrongEtag(body) {
const buf = Buffer.isBuffer(body) ? body : Buffer.from(String(body));
const digest = crypto.createHash('sha1').update(buf).digest('base64');
return '"' + digest + '"';
CREATE TABLE password_reset_tokens (
id BIGSERIAL PRIMARY KEY,
user_id BIGINT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
token_hash TEXT NOT NULL,
expires_at TIMESTAMPTZ NOT NULL,
used_at TIMESTAMPTZ,
const express = require('express');
const multer = require('multer');
const os = require('os');
const fs = require('fs/promises');
const { parseCsvStream } = require('./csvStreamParser');
import { randomBytes } from 'crypto';
import { Request, Response, NextFunction } from 'express';
interface CspOptions {
reportOnly?: boolean;
reportUri?: string;