Infrastructure only — no existing data or tables modified.
src/db/migrate.js — programmatic runner, fires at boot after
the existing idempotent initDatabase()
migrations/1744600000000... — intentionally empty example, documents
the file shape. Registered in the new
pgmigrations tracking table so it won't
rerun.
.node-pg-migraterc.json — CLI config (migrations-dir, utc naming)
docs/migrations.md — workflow + conventions
package.json — migrate:up/down/new/status npm scripts
(status is a direct pgmigrations query
since node-pg-migrate v7 lacks a status
subcommand)
src/utils/sessions.js:
- parseUserAgent now recognizes the Capacitor wrapper (UA suffix
"PedScribe-Android" / "PedScribe-iOS") and labels sessions
"PedScribe (Android)" instead of "Chrome on Android".
Going forward: schema changes go in /migrations as versioned files
with up() + down(); the inline init in database.js is the implicit
baseline for everything already in production.
42 lines
1.4 KiB
JavaScript
42 lines
1.4 KiB
JavaScript
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 };
|