All remaining backend files renamed:
src/middleware/auth.ts, logging.ts (2 files)
src/utils/*.ts (20 files: ai, auditQueue, config, crypto,
embeddings, errors, fileType, logger, models,
notify, passwords, platform, promptSafe,
prompts, redact, sessions, transcribe*,
ttsGoogle)
src/db/database.ts, migrate.ts (2 files)
Spot-fixes to satisfy tsc (all within the spirit of 'no behavior
change' — added `: any` annotations where the original JS relied on
duck typing that tsc's default inference narrows too aggressively):
utils/ai.ts — body, converseParams, request literals + fallback
result object + err.code/model/message casts. AI client has lots
of provider-specific ad-hoc object shapes; Day 5 will replace the
`any`s with proper provider-response interfaces.
utils/embeddings.ts — payload + request as `any`; generateEmbedding
call sites pass `undefined as any` for the now-required second
arg (model) until we refactor the signature.
utils/prompts.ts — PROMPTS typed as Record<string, any> so
.loadFromDb / .updatePrompt / .getAllPrompts attachments after
the const literal compile.
utils/transcribeLocal.ts — buildArgs() has two `var args = [...]`
in the same function scope (var-hoisted); both now typed as
any[] so they don't type-clash across conditionals.
Backend is now 54 of 54 TypeScript files, permissive mode.
`npm run typecheck` EXIT 0. Prod container still running the old
JS image — no Dockerfile change yet.
Next: Day 5 flips strict: true, fixes every error tsc surfaces, adds
Vitest + Zod + Knip tooling.
42 lines
1.4 KiB
TypeScript
42 lines
1.4 KiB
TypeScript
var crypto = require('crypto');
|
|
|
|
function hashToken(token) {
|
|
return crypto.createHash('sha256').update(token).digest('hex');
|
|
}
|
|
|
|
function parseUserAgent(ua) {
|
|
if (!ua) return 'Unknown device';
|
|
|
|
// Native PedScribe app (Capacitor appends "PedScribe-Android" / "PedScribe-iOS")
|
|
if (/PedScribe-Android/i.test(ua)) return 'PedScribe (Android)';
|
|
if (/PedScribe-iOS/i.test(ua)) return 'PedScribe (iOS)';
|
|
if (/Capacitor/i.test(ua)) {
|
|
if (/Android/i.test(ua)) return 'PedScribe (Android)';
|
|
if (/iPhone|iPad|iOS/i.test(ua)) return 'PedScribe (iOS)';
|
|
return 'PedScribe app';
|
|
}
|
|
|
|
var browser = 'Unknown browser';
|
|
var os = 'Unknown OS';
|
|
|
|
if (/Edg\//.test(ua)) browser = 'Edge';
|
|
else if (/OPR\/|Opera/.test(ua)) browser = 'Opera';
|
|
else if (/Firefox\//.test(ua)) browser = 'Firefox';
|
|
else if (/Safari\//.test(ua) && !/Chrome/.test(ua)) browser = 'Safari';
|
|
else if (/Chrome\//.test(ua)) browser = 'Chrome';
|
|
|
|
if (/Windows/.test(ua)) os = 'Windows';
|
|
else if (/Mac OS X/.test(ua)) os = 'macOS';
|
|
else if (/Android/.test(ua)) os = 'Android';
|
|
else if (/iPhone|iPad/.test(ua)) os = 'iOS';
|
|
else if (/Linux/.test(ua)) os = 'Linux';
|
|
else if (/CrOS/.test(ua)) os = 'ChromeOS';
|
|
|
|
return browser + ' on ' + os;
|
|
}
|
|
|
|
function generateSessionId() {
|
|
return crypto.randomUUID();
|
|
}
|
|
|
|
module.exports = { hashToken, parseUserAgent, generateSessionId };
|