'use strict'; const CaptureQuality = require('../js/capture-quality.js'); const HeadPose = require('../js/head-pose.js'); const views = ['front', 'left', 'right']; function scalar(value) { return typeof value === 'number' && Number.isFinite(value) ? value : null; } // Client observations are untrusted calibration hints, never authorization or // a provider-quality verdict. Strip arbitrary strings/extra fields on ingestion. function normalize(input) { if (!input || typeof input !== 'object') return null; const version = typeof input.version === 'string' && /^[\w.-]{1,64}$/.test(input.version) ? input.version : 'unknown'; const result = { version, source: 'client-untrusted', views: {} }; for (const key of views) { const row = input.views && input.views[key]; if (!row || typeof row !== 'object') continue; const out = { mode: ['live', 'file', 'unchecked', 'mock'].includes(row.mode) ? row.mode : 'unknown' }; if (row.reason === 'model-unavailable') out.reason = row.reason; if (typeof row.direction_checked === 'boolean') out.direction_checked = row.direction_checked; for (const metric of ['yaw', 'pitch', 'roll', 'score', 'luma', 'ratio', 'center_x', 'center_y']) { const value = scalar(row[metric]); if (value != null && Math.abs(value) <= 1000) out[metric] = value; } result.views[key] = out; } if (version === CaptureQuality.config.version) result.policy = { capture: CaptureQuality.config, pose: HeadPose.config }; return result; } function assess(raw) { const nested = raw.side_result || {}; const result = { status: 'valid', views: {} }; for (const key of ['left', 'right']) { const side = raw[key + '_side_result'] || nested[key + '_side_result']; const node = side && side[key + '_jawline_info']; const quality = scalar(node && node[key + '_jawline_quality']); const angle = scalar(node && node[key + '_jawline_angle']); const status = quality == null ? 'unavailable' : quality === 1 && angle != null ? 'valid' : 'invalid'; result.views[key] = { quality, angle, status }; if (status === 'invalid') result.status = 'invalid'; else if (status === 'unavailable' && result.status === 'valid') result.status = 'unavailable'; } return result; } module.exports = { normalize, assess };