UNPKG

@documedis-components/prescription-sign

Version:

React component for signing electronic prescriptions with HIN authentication

247 lines (246 loc) 9.35 kB
import { Environment } from '../../../../../core/src/infrastructure/shared'; export interface PrescriptionSignProps { /** * Environment configuration for the prescription service * - 'local': Development environment (localhost:52247) * - 'dev': Development Azure Container Apps * - 'int': Integration Azure Container Apps * - 'prod': Production Azure Container Apps */ environment: Environment; /** Base64-encoded CHMED prescription data to be signed */ chmed: string; /** Access token for authenticating with the backend service */ accessToken: string; /** * Optional existing session token to reuse authentication state. * If provided, the component will attempt to use existing authentication. */ sessionToken?: string; /** * Optional callback invoked when the session token is updated. * Use this to persist the session token for reuse across components. */ onSessionTokenUpdate?: (sessionToken: string) => void; /** * Optional callback invoked when prescription signing succeeds. * Receives the signed CHMED data as a base64-encoded string. */ onSuccess?: (signedCHMED: string) => void; /** * Optional callback invoked when prescription signing fails. * Receives a specific error type indicating what went wrong. */ onError?: (error: PrescriptionSignErrorType) => void; /** * Optional logger for detailed process tracking. * Provides step-by-step information about the signing process. */ logger?: PrescriptionSignLogger; /** Optional additional CSS class names to apply to the component */ className?: string; } /** * Internal events used by the prescription signing state machine * These events coordinate the complex authentication and signing workflow */ export type PrescriptionSignEvents = { type: 'OPEN_POPUP'; popupRef: Window | null; } | { type: 'CLOSE_POPUP'; } | { type: 'START'; encodedCHMED: string; } | { type: 'TERMINATE'; } | { type: 'VERIFY_SESSION'; } | { type: 'REFRESH_TOKEN'; } | { type: 'GET_TOKEN'; } | { type: 'GET_SAML_AUTH_CODE'; recoverable?: boolean; } | { type: 'GET_SAML_AUTH_HANDLE'; authCode: string; } | { type: 'VALIDATE_CHMED'; } | { type: 'SIGN_PRESCRIPTION'; } | { type: 'AUTHENTICATION_SUCCESS'; } | { type: 'ERROR'; error: PrescriptionSignErrorType; details?: { message?: string; originalError?: unknown; context?: Record<string, unknown>; }; } | { type: 'UNAUTHORIZED_TOKEN'; } | { type: 'UNAUTHORIZED_HANDLE'; }; /** * Specific error types that can occur during prescription signing */ export type PrescriptionSignErrorType = /** User canceled the signing process */ 'canceled' /** Authentication popup window was closed by user */ | 'popupClosed' /** Browser blocked the authentication popup window */ | 'popupBlocked' /** HIN authentication failed */ | 'login' /** Invalid or malformed CHMED prescription data */ | 'chmed' /** OAuth authentication with HIN failed */ | 'oauth' /** Failed to obtain SAML authorization code */ | 'authCode' /** Failed to obtain SAML authentication handle */ | 'authHandle' /** Failed to digitally sign the prescription */ | 'signature'; /** * Internal context used by the prescription signing state machine */ export type PrescriptionSignContext = { /** The CHMED data being processed (base64-encoded) */ encodedCHMED?: string; /** The signed CHMED data returned from HIN (base64-encoded) */ signedCHMED?: string; /** Reference to the authentication popup window */ popupRef: Window | null; /** Skip session restoration logs when verifying session after fresh operations */ skipRestorationLogs?: boolean; }; /** * Structured log event types for programmatic reaction by developers. * These events enable monitoring, debugging, and analytics of the prescription signing process. */ export type PrescriptionSignLogEvent = PrescriptionSignFlowEvent | PrescriptionSignErrorEvent; /** * Flow events for tracking prescription signing progress. * Emitted at various stages of the signing process to provide visibility into the workflow. * * @example * ```typescript * logger.emit({ * type: 'flow_step_started', * phase: 'authentication', * step: 'saml_auth_initiated', * timestamp: new Date() * }); * ``` */ export type PrescriptionSignFlowEvent = { /** Event type indicating the nature of the flow event */ type: 'flow_started' | 'flow_step_started' | 'flow_step_completed' | 'flow_completed'; /** Current phase of the prescription signing process */ phase: 'initialization' | 'securisation' | 'authentication' | 'authorization' | 'validation' | 'signing' | 'completion'; /** Specific step within the current phase */ step: PrescriptionSignFlowStep; /** Timestamp when the event occurred */ timestamp: Date; /** Optional contextual information about the event (e.g., user ID, session info) */ context?: Record<string, unknown>; /** Optional data specific to this event (e.g., token expiry, validation results) */ data?: Record<string, unknown>; }; /** * Error events with structured data for programmatic error handling. * Provides detailed information about failures to enable proper error recovery and user feedback. * * @example * ```typescript * logger.emit({ * type: 'error', * errorType: 'popupBlocked', * phase: 'authentication', * step: 'popup_opened', * timestamp: new Date(), * message: 'Browser blocked authentication popup' * }); * ``` */ export type PrescriptionSignErrorEvent = { /** Indicates this is an error event */ type: 'error'; /** Categorized error type for programmatic handling */ errorType: PrescriptionSignErrorType; /** Phase where the error occurred */ phase: 'initialization' | 'securisation' | 'authentication' | 'authorization' | 'validation' | 'signing'; /** Specific step where the error occurred */ step: PrescriptionSignFlowStep; /** Timestamp when the error occurred */ timestamp: Date; /** Original error object if available (e.g., network error, API response) */ originalError?: unknown; /** Additional context about the error (e.g., HTTP status, request ID) */ context?: Record<string, unknown>; /** Human-readable error message for debugging */ message?: string; }; /** * Detailed flow steps for granular progress tracking. * Each step represents a specific point in the prescription signing workflow. * Steps are organized by phase to help developers understand the process flow. */ export type PrescriptionSignFlowStep = 'process_started' | 'popup_opened' | 'saml_handle_retrieved_from_session' | 'oauth_token_retrieved_from_session' | 'oauth_token_eligible_for_refresh' | 'authentication_ready' | 'authentication_completed' | 'saml_auth_initiated' | 'saml_auth_completed' | 'oauth_flow_initiated' | 'oauth_code_received' | 'oauth_token_received' | 'token_refresh_initiated' | 'token_refreshed' | 'saml_auth_code_initiated' | 'saml_code_received' | 'saml_handle_initiated' | 'saml_handle_received' | 'chmed_validation_started' | 'chmed_validation_completed' | 'prescription_signing_started' | 'prescription_signing_completed' | 'process_completed' | 'process_terminated'; /** * Logger interface for emitting structured events that developers can programmatically react to * This is designed for component library usage, not end-user applications */ export type PrescriptionSignLogger = { /** * Emit a structured log event for programmatic consumption * @param event - Structured event data that developers can filter, react to, and process */ emit: (event: PrescriptionSignLogEvent) => void; }; /** * Props for the usePrescriptionSigning hook */ export type UsePrescriptionSigningProps = { /** * Environment configuration for the prescription service * - 'local': Development environment (localhost:52247) * - 'dev': Development Azure Container Apps * - 'int': Integration Azure Container Apps * - 'prod': Production Azure Container Apps */ environment: Environment; /** Access token for authenticating with the backend service */ accessToken: string; /** * Optional existing session token to reuse authentication state. * If provided, the hook will attempt to use existing authentication. */ sessionToken?: string; /** * Optional callback invoked when the session token is updated. * Use this to persist the session token for reuse across hook instances. */ onSessionTokenUpdate?: (token: string) => void; /** * Optional callback invoked when prescription signing succeeds. * Receives the signed CHMED data as a base64-encoded string. */ onSuccess?: (signedCHMED: string) => void; /** * Optional callback invoked when prescription signing fails. * Receives a specific error type indicating what went wrong. */ onError?: (error: PrescriptionSignErrorType) => void; /** * Optional logger for step-by-step process tracking. * Emits detailed events throughout the signing process for debugging and monitoring. */ logger?: PrescriptionSignLogger; };