@striae-org/striae 4.0.1 → 4.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/.env.example +1 -0
  2. package/app/components/actions/case-export/data-processing.ts +1 -1
  3. package/app/components/actions/case-export/download-handlers.ts +4 -3
  4. package/app/components/actions/case-export/metadata-helpers.ts +1 -1
  5. package/app/components/actions/case-import/confirmation-import.ts +1 -1
  6. package/app/components/actions/case-import/image-operations.ts +1 -1
  7. package/app/components/actions/case-import/orchestrator.ts +1 -1
  8. package/app/components/actions/case-import/storage-operations.ts +3 -3
  9. package/app/components/actions/case-import/validation.ts +3 -4
  10. package/app/components/actions/case-import/zip-processing.ts +1 -1
  11. package/app/components/actions/case-manage.ts +3 -5
  12. package/app/components/actions/confirm-export.ts +4 -5
  13. package/app/components/actions/generate-pdf.ts +1 -1
  14. package/app/components/actions/image-manage.ts +2 -3
  15. package/app/components/actions/notes-manage.ts +1 -1
  16. package/app/components/actions/signout.tsx +1 -1
  17. package/app/components/audit/user-audit-viewer.tsx +1 -1
  18. package/app/components/auth/auth-provider.tsx +1 -1
  19. package/app/components/auth/mfa-verification.tsx +1 -1
  20. package/app/components/button/button.tsx +1 -1
  21. package/app/components/canvas/box-annotations/box-annotations.tsx +1 -1
  22. package/app/components/canvas/confirmation/confirmation.tsx +1 -1
  23. package/app/components/icon/icon.tsx +1 -1
  24. package/app/components/public-signing-key-modal/public-signing-key-modal.tsx +1 -1
  25. package/app/components/sidebar/case-export/case-export.tsx +1 -1
  26. package/app/components/sidebar/cases/case-sidebar.tsx +3 -3
  27. package/app/components/sidebar/cases/cases-modal.tsx +1 -1
  28. package/app/components/sidebar/files/files-modal.tsx +1 -1
  29. package/app/components/sidebar/notes/notes-sidebar.tsx +1 -1
  30. package/app/components/sidebar/sidebar-container.tsx +2 -17
  31. package/app/components/sidebar/sidebar.module.css +0 -29
  32. package/app/components/theme-provider/theme-provider.tsx +1 -1
  33. package/app/components/theme-provider/theme.ts +1 -1
  34. package/app/components/user/delete-account.tsx +1 -1
  35. package/app/components/user/manage-profile.tsx +1 -1
  36. package/app/components/user/mfa-phone-update.tsx +1 -1
  37. package/app/root.tsx +18 -51
  38. package/app/routes/auth/emailActionHandler.tsx +1 -2
  39. package/app/routes/auth/emailVerification.tsx +1 -1
  40. package/app/routes/auth/login.example.tsx +775 -0
  41. package/app/routes/auth/login.module.example.css +523 -0
  42. package/app/routes/auth/login.tsx +4 -6
  43. package/app/routes/auth/passwordReset.tsx +1 -1
  44. package/app/routes/striae/striae.tsx +2 -2
  45. package/app/services/audit/audit-export-signing.ts +2 -2
  46. package/app/services/audit/audit-export.service.ts +1 -2
  47. package/app/services/audit/audit.service.ts +1 -1
  48. package/app/services/firebase/index.ts +1 -1
  49. package/app/utils/api/index.ts +4 -0
  50. package/app/utils/auth/index.ts +5 -0
  51. package/app/utils/common/index.ts +3 -0
  52. package/app/utils/{version.ts → common/version.ts} +1 -1
  53. package/app/utils/{data-operations.ts → data/data-operations.ts} +4 -4
  54. package/app/utils/data/index.ts +2 -0
  55. package/app/utils/{permissions.ts → data/permissions.ts} +1 -1
  56. package/app/utils/forensics/index.ts +5 -0
  57. package/app/utils/ui/index.ts +2 -0
  58. package/package.json +18 -20
  59. package/public/.well-known/keybase.txt +56 -0
  60. package/scripts/deploy-config.sh +29 -0
  61. package/scripts/deploy-worker-secrets.sh +1 -2
  62. package/workers/audit-worker/wrangler.jsonc.example +1 -1
  63. package/workers/data-worker/wrangler.jsonc.example +1 -1
  64. package/workers/image-worker/wrangler.jsonc.example +1 -1
  65. package/workers/keys-worker/wrangler.jsonc.example +1 -1
  66. package/workers/pdf-worker/src/pdf-worker.example.ts +144 -39
  67. package/workers/pdf-worker/wrangler.jsonc.example +1 -1
  68. package/workers/user-worker/wrangler.jsonc.example +1 -1
  69. package/wrangler.toml.example +1 -1
  70. package/public/.well-known/publickey.info@striae.org.asc +0 -17
  71. package/public/oin-badge.png +0 -0
  72. /package/app/utils/{data-api-client.ts → api/data-api-client.ts} +0 -0
  73. /package/app/utils/{image-api-client.ts → api/image-api-client.ts} +0 -0
  74. /package/app/utils/{pdf-api-client.ts → api/pdf-api-client.ts} +0 -0
  75. /package/app/utils/{user-api-client.ts → api/user-api-client.ts} +0 -0
  76. /package/app/utils/{auth-action-settings.ts → auth/auth-action-settings.ts} +0 -0
  77. /package/app/utils/{auth.ts → auth/auth.ts} +0 -0
  78. /package/app/utils/{mfa-phone.ts → auth/mfa-phone.ts} +0 -0
  79. /package/app/utils/{mfa.ts → auth/mfa.ts} +0 -0
  80. /package/app/utils/{password-policy.ts → auth/password-policy.ts} +0 -0
  81. /package/app/utils/{batch-operations.ts → common/batch-operations.ts} +0 -0
  82. /package/app/utils/{id-generator.ts → common/id-generator.ts} +0 -0
  83. /package/app/utils/{SHA256.ts → forensics/SHA256.ts} +0 -0
  84. /package/app/utils/{audit-export-signature.ts → forensics/audit-export-signature.ts} +0 -0
  85. /package/app/utils/{confirmation-signature.ts → forensics/confirmation-signature.ts} +0 -0
  86. /package/app/utils/{export-verification.ts → forensics/export-verification.ts} +0 -0
  87. /package/app/utils/{signature-utils.ts → forensics/signature-utils.ts} +0 -0
  88. /package/app/utils/{annotation-timestamp.ts → ui/annotation-timestamp.ts} +0 -0
  89. /package/app/utils/{style.ts → ui/style.ts} +0 -0
package/.env.example CHANGED
@@ -88,6 +88,7 @@ HMAC_KEY=your_cloudflare_images_hmac_key_here
88
88
  PDF_WORKER_NAME=your_pdf_worker_name_here
89
89
  PDF_WORKER_DOMAIN=your_pdf_worker_domain_here
90
90
  PDF_WORKER_AUTH=your_custom_pdf_worker_auth_token_here
91
+ BROWSER_API_TOKEN=your_cloudflare_browser_rendering_api_token_here
91
92
 
92
93
  # ================================
93
94
  # QUICK MANUAL SETUP CHECKLIST
@@ -1,5 +1,5 @@
1
1
  import { type CaseExportData } from '~/types';
2
- import { calculateSHA256Secure } from '~/utils/SHA256';
2
+ import { calculateSHA256Secure } from '~/utils/forensics';
3
3
  import { CSV_HEADERS } from './types-constants';
4
4
  import { addForensicDataWarning } from './metadata-helpers';
5
5
 
@@ -2,13 +2,14 @@ import type { User } from 'firebase/auth';
2
2
  import type * as ExcelJSModule from 'exceljs';
3
3
  import { type FileData, type AllCasesExportData, type CaseExportData, type ExportOptions } from '~/types';
4
4
  import { getImageUrl } from '../image-manage';
5
- import { generateForensicManifestSecure, calculateSHA256Secure } from '~/utils/SHA256';
6
- import { signForensicManifest } from '~/utils/data-operations';
7
5
  import {
6
+ generateForensicManifestSecure,
7
+ calculateSHA256Secure,
8
8
  createPublicSigningKeyFileName,
9
9
  getCurrentPublicSigningKeyDetails,
10
10
  getVerificationPublicKey
11
- } from '~/utils/signature-utils';
11
+ } from '~/utils/forensics';
12
+ import { signForensicManifest } from '~/utils/data';
12
13
  import { type ExportFormat, formatDateForFilename, CSV_HEADERS } from './types-constants';
13
14
  import { protectExcelWorksheet, addForensicDataWarning } from './metadata-helpers';
14
15
  import { generateMetadataRows, generateCSVContent, processFileDataForTabular, sanitizeTabularMatrix } from './data-processing';
@@ -1,5 +1,5 @@
1
1
  import type { User } from 'firebase/auth';
2
- import { getUserData } from '~/utils/permissions';
2
+ import { getUserData } from '~/utils/data';
3
3
 
4
4
  /**
5
5
  * Helper function to get user export metadata
@@ -1,5 +1,5 @@
1
1
  import type { User } from 'firebase/auth';
2
- import { fetchDataApi } from '~/utils/data-api-client';
2
+ import { fetchDataApi } from '~/utils/api';
3
3
  import { type ConfirmationImportResult, type ConfirmationImportData } from '~/types';
4
4
  import { checkExistingCase } from '../case-manage';
5
5
  import { extractConfirmationImportPackage } from './confirmation-package';
@@ -1,5 +1,5 @@
1
1
  import type { User } from 'firebase/auth';
2
- import { uploadImageApi } from '~/utils/image-api-client';
2
+ import { uploadImageApi } from '~/utils/api';
3
3
  import { type FileData } from '~/types';
4
4
 
5
5
  /**
@@ -6,7 +6,7 @@ import {
6
6
  type SignedForensicManifest,
7
7
  validateCaseIntegritySecure as validateForensicIntegrity,
8
8
  verifyForensicManifestSignature
9
- } from '~/utils/SHA256';
9
+ } from '~/utils/forensics';
10
10
  import { deleteFile } from '../image-manage';
11
11
  import { parseImportZip } from './zip-processing';
12
12
  import {
@@ -1,10 +1,10 @@
1
1
  import type { User } from 'firebase/auth';
2
- import { fetchDataApi } from '~/utils/data-api-client';
2
+ import { fetchDataApi } from '~/utils/api';
3
3
  import {
4
4
  getUserReadOnlyCases,
5
5
  updateUserData,
6
6
  validateUserSession
7
- } from '~/utils/permissions';
7
+ } from '~/utils/data';
8
8
  import {
9
9
  type CaseExportData,
10
10
  type FileData,
@@ -12,7 +12,7 @@ import {
12
12
  type ReadOnlyCaseMetadata
13
13
  } from '~/types';
14
14
  import { deleteFile } from '../image-manage';
15
- import { type SignedForensicManifest } from '~/utils/SHA256';
15
+ import { type SignedForensicManifest } from '~/utils/forensics';
16
16
 
17
17
  /**
18
18
  * Check if user already has a read-only case with the same number
@@ -1,9 +1,8 @@
1
1
  import type { User } from 'firebase/auth';
2
- import { checkUserExistsApi } from '~/utils/user-api-client';
2
+ import { checkUserExistsApi } from '~/utils/api';
3
3
  import { type CaseExportData, type ConfirmationImportData } from '~/types';
4
- import { type ManifestSignatureVerificationResult } from '~/utils/SHA256';
5
- import { verifyConfirmationSignature } from '~/utils/confirmation-signature';
6
- export { removeForensicWarning, validateConfirmationHash } from '~/utils/export-verification';
4
+ import { type ManifestSignatureVerificationResult, verifyConfirmationSignature } from '~/utils/forensics';
5
+ export { removeForensicWarning, validateConfirmationHash } from '~/utils/forensics';
7
6
 
8
7
  /**
9
8
  * Validate that a user exists in the database by UID and is not the current user
@@ -6,7 +6,7 @@ import {
6
6
  type SignedForensicManifest,
7
7
  validateCaseIntegritySecure as validateForensicIntegrity,
8
8
  verifyForensicManifestSignature
9
- } from '~/utils/SHA256';
9
+ } from '~/utils/forensics';
10
10
  import { validateExporterUid, removeForensicWarning } from './validation';
11
11
 
12
12
  function getLeafFileName(path: string): string {
@@ -4,18 +4,16 @@ import {
4
4
  getUserCases,
5
5
  validateUserSession,
6
6
  addUserCase,
7
- removeUserCase
8
- } from '~/utils/permissions';
9
- import {
7
+ removeUserCase,
10
8
  getCaseData,
11
9
  updateCaseData,
12
10
  deleteCaseData,
13
11
  duplicateCaseData,
14
12
  deleteFileAnnotations
15
- } from '~/utils/data-operations';
13
+ } from '~/utils/data';
16
14
  import { type CaseData, type ReadOnlyCaseData, type FileData } from '~/types';
17
15
  import { auditService } from '~/services/audit';
18
- import { fetchImageApi } from '~/utils/image-api-client';
16
+ import { fetchImageApi } from '~/utils/api';
19
17
 
20
18
  /**
21
19
  * Delete a file without individual audit logging (for bulk operations)
@@ -1,13 +1,12 @@
1
1
  import type { User } from 'firebase/auth';
2
- import { calculateSHA256Secure } from '~/utils/SHA256';
3
- import { getUserData } from '~/utils/permissions';
4
- import { getCaseData, updateCaseData, signConfirmationData } from '~/utils/data-operations';
5
- import { type ConfirmationData, type CaseConfirmations, type CaseDataWithConfirmations, type ConfirmationImportData } from '~/types';
6
2
  import {
3
+ calculateSHA256Secure,
7
4
  createPublicSigningKeyFileName,
8
5
  getCurrentPublicSigningKeyDetails,
9
6
  getVerificationPublicKey
10
- } from '~/utils/signature-utils';
7
+ } from '~/utils/forensics';
8
+ import { getUserData, getCaseData, updateCaseData, signConfirmationData } from '~/utils/data';
9
+ import { type ConfirmationData, type CaseConfirmations, type CaseDataWithConfirmations, type ConfirmationImportData } from '~/types';
11
10
  import { auditService } from '~/services/audit';
12
11
 
13
12
  /**
@@ -1,7 +1,7 @@
1
1
  import { type AnnotationData } from '~/types/annotations';
2
2
  import { auditService } from '~/services/audit';
3
3
  import type { User } from 'firebase/auth';
4
- import { fetchPdfApi } from '~/utils/pdf-api-client';
4
+ import { fetchPdfApi } from '~/utils/api';
5
5
 
6
6
  interface GeneratePDFParams {
7
7
  user: User;
@@ -2,9 +2,8 @@ import type { User } from 'firebase/auth';
2
2
  import {
3
3
  getAccountHash
4
4
  } from '~/utils/auth';
5
- import { fetchImageApi, uploadImageApi } from '~/utils/image-api-client';
6
- import { canUploadFile } from '~/utils/permissions';
7
- import { getCaseData, updateCaseData, deleteFileAnnotations } from '~/utils/data-operations';
5
+ import { fetchImageApi, uploadImageApi } from '~/utils/api';
6
+ import { canUploadFile, getCaseData, updateCaseData, deleteFileAnnotations } from '~/utils/data';
8
7
  import type { CaseData, FileData, ImageUploadResponse } from '~/types';
9
8
  import { auditService } from '~/services/audit';
10
9
 
@@ -1,6 +1,6 @@
1
1
  import type { User } from 'firebase/auth';
2
2
  import { type AnnotationData } from '~/types/annotations';
3
- import { saveFileAnnotations, getFileAnnotations, type DataOperationOptions } from '~/utils/data-operations';
3
+ import { saveFileAnnotations, getFileAnnotations, type DataOperationOptions } from '~/utils/data';
4
4
 
5
5
  export const saveNotes = async (
6
6
  user: User,
@@ -1,6 +1,6 @@
1
1
  import { auth } from '~/services/firebase';
2
2
  import { auditService } from '~/services/audit';
3
- import { generateUniqueId } from '~/utils/id-generator';
3
+ import { generateUniqueId } from '~/utils/common';
4
4
  import styles from './signout.module.css';
5
5
 
6
6
  interface SignOutProps {
@@ -2,7 +2,7 @@ import { useState, useEffect, useContext, useCallback } from 'react';
2
2
  import { AuthContext } from '~/contexts/auth.context';
3
3
  import { auditService, auditExportService } from '~/services/audit';
4
4
  import { type ValidationAuditEntry, type AuditAction, type AuditResult, type AuditTrail, type UserData, type WorkflowPhase } from '~/types';
5
- import { getUserData } from '~/utils/permissions';
5
+ import { getUserData } from '~/utils/data';
6
6
  import styles from './user-audit.module.css';
7
7
 
8
8
  const isWorkflowPhase = (phase: unknown): phase is WorkflowPhase =>
@@ -6,7 +6,7 @@ import { INACTIVITY_CONFIG } from '~/config/inactivity';
6
6
  import { AuthContext } from '~/contexts/auth.context';
7
7
  import { InactivityWarning } from '~/components/user/inactivity-warning';
8
8
  import { auditService } from '~/services/audit';
9
- import { generateUniqueId } from '~/utils/id-generator';
9
+ import { generateUniqueId } from '~/utils/common';
10
10
 
11
11
  interface AuthProviderProps {
12
12
  children: React.ReactNode;
@@ -10,7 +10,7 @@ import { auth } from '~/services/firebase';
10
10
  import { handleAuthError, getValidationError } from '~/services/firebase/errors';
11
11
  import { SignOut } from '~/components/actions/signout';
12
12
  import { auditService } from '~/services/audit';
13
- import { generateUniqueId } from '~/utils/id-generator';
13
+ import { generateUniqueId } from '~/utils/common';
14
14
  import styles from './mfa-verification.module.css';
15
15
 
16
16
  interface MFAVerificationProps {
@@ -1,6 +1,6 @@
1
1
  import { Icon } from '../icon/icon';
2
2
  import styles from './button.module.css';
3
- import { classes } from '~/utils/style';
3
+ import { classes } from '~/utils/ui';
4
4
 
5
5
  interface ButtonProps {
6
6
  iconId: string;
@@ -2,7 +2,7 @@ import { useState, useCallback, useMemo, useRef, useEffect, useContext } from 'r
2
2
  import { type BoxAnnotation } from '~/types';
3
3
  import { AuthContext } from '~/contexts/auth.context';
4
4
  import { auditService } from '~/services/audit';
5
- import { resolveEarliestAnnotationTimestamp } from '~/utils/annotation-timestamp';
5
+ import { resolveEarliestAnnotationTimestamp } from '~/utils/ui';
6
6
  import styles from './box-annotations.module.css';
7
7
 
8
8
  // Constants
@@ -1,7 +1,7 @@
1
1
  import { useState, useEffect, useContext } from 'react';
2
2
  import { type ConfirmationData } from '~/types/annotations';
3
3
  import { AuthContext } from '~/contexts/auth.context';
4
- import { generateConfirmationId } from '~/utils/id-generator';
4
+ import { generateConfirmationId } from '~/utils/common';
5
5
  import styles from './confirmation.module.css';
6
6
 
7
7
  interface ConfirmationModalProps {
@@ -1,4 +1,4 @@
1
- import { classes } from '~/utils/style';
1
+ import { classes } from '~/utils/ui';
2
2
  import styles from './icon.module.css';
3
3
  import { forwardRef } from 'react';
4
4
  import sprites from './icons.svg';
@@ -9,7 +9,7 @@ import {
9
9
  type MouseEvent
10
10
  } from 'react';
11
11
  import styles from './public-signing-key-modal.module.css';
12
- import { verifyExportFile } from '~/utils/export-verification';
12
+ import { verifyExportFile } from '~/utils/forensics';
13
13
 
14
14
  const NO_PUBLIC_KEY_MESSAGE = 'No public signing key is configured for this environment.';
15
15
 
@@ -2,7 +2,7 @@ import { useState, useEffect, useContext } from 'react';
2
2
  import styles from './case-export.module.css';
3
3
  import { AuthContext } from '~/contexts/auth.context';
4
4
  import { PublicSigningKeyModal } from '~/components/public-signing-key-modal/public-signing-key-modal';
5
- import { getCurrentPublicSigningKeyDetails } from '~/utils/signature-utils';
5
+ import { getCurrentPublicSigningKeyDetails } from '~/utils/forensics';
6
6
  import { getCaseConfirmations, exportConfirmationData } from '../../actions/confirm-export';
7
7
 
8
8
  export type ExportFormat = 'json' | 'csv';
@@ -26,9 +26,9 @@ import {
26
26
  canCreateCase,
27
27
  canUploadFile,
28
28
  getLimitsDescription,
29
- getUserData
30
- } from '~/utils/permissions';
31
- import { getFileAnnotations } from '~/utils/data-operations';
29
+ getUserData,
30
+ getFileAnnotations
31
+ } from '~/utils/data';
32
32
  import { type FileData, type CaseActionType } from '~/types';
33
33
 
34
34
  interface CaseSidebarProps {
@@ -1,7 +1,7 @@
1
1
  import { useState, useEffect } from 'react';
2
2
  import type { User } from 'firebase/auth';
3
3
  import { listCases } from '~/components/actions/case-manage';
4
- import { getFileAnnotations } from '~/utils/data-operations';
4
+ import { getFileAnnotations } from '~/utils/data';
5
5
  import { fetchFiles } from '~/components/actions/image-manage';
6
6
  import styles from './cases-modal.module.css';
7
7
 
@@ -2,7 +2,7 @@ import type React from 'react';
2
2
  import { useState, useContext, useEffect } from 'react';
3
3
  import { AuthContext } from '~/contexts/auth.context';
4
4
  import { deleteFile } from '~/components/actions/image-manage';
5
- import { getFileAnnotations } from '~/utils/data-operations';
5
+ import { getFileAnnotations } from '~/utils/data';
6
6
  import { type FileData } from '~/types';
7
7
  import styles from './files-modal.module.css';
8
8
 
@@ -4,7 +4,7 @@ import { ColorSelector } from '~/components/colors/colors';
4
4
  import { NotesModal } from './notes-modal';
5
5
  import { getNotes, saveNotes } from '~/components/actions/notes-manage';
6
6
  import { type AnnotationData } from '~/types/annotations';
7
- import { resolveEarliestAnnotationTimestamp } from '~/utils/annotation-timestamp';
7
+ import { resolveEarliestAnnotationTimestamp } from '~/utils/ui';
8
8
  import { auditService } from '~/services/audit';
9
9
  import styles from './notes.module.css';
10
10
 
@@ -7,7 +7,7 @@ import { Sidebar } from './sidebar';
7
7
  import type { User } from 'firebase/auth';
8
8
  import { type FileData } from '~/types';
9
9
  import styles from './sidebar.module.css';
10
- import { getAppVersion } from '../../utils/version';
10
+ import { getAppVersion } from '~/utils/common';
11
11
 
12
12
  interface SidebarContainerProps {
13
13
  user: User;
@@ -121,22 +121,7 @@ export const SidebarContainer: React.FC<SidebarContainerProps> = (props) => {
121
121
  Security Policy
122
122
  </Link>
123
123
  </div>
124
- <div className={styles.badgeContainer}>
125
- <div className={styles.oinBadge}>
126
- <a
127
- href="https://openinventionnetwork.com/"
128
- target="_blank"
129
- rel="noopener noreferrer"
130
- className={styles.oinBadgeLink}
131
- >
132
- <img
133
- src="/oin-badge.png"
134
- alt="Open Invention Network Community Member"
135
- className={styles.oinBadgeImage}
136
- />
137
- </a>
138
- </div>
139
- </div>
124
+
140
125
  <div className={styles.footerModalCopyright}>
141
126
  <a href={`https://github.com/striae-org/striae/releases/tag/v${appVersion}`} className={styles.link} target="_blank" rel="noopener noreferrer">Striae v{appVersion}</a> © {year}.{' '}
142
127
  Licensed under Apache 2.0.
@@ -237,36 +237,7 @@
237
237
  text-underline-offset: 3px;
238
238
  }
239
239
 
240
- .badgeContainer {
241
- display: flex;
242
- justify-content: center;
243
- align-items: center;
244
- gap: var(--spaceM, 1rem);
245
- margin-top: var(--spaceXS, 0.5rem);
246
- flex-wrap: wrap;
247
- width: 100%;
248
- }
249
-
250
- .oinBadge {
251
- text-align: center;
252
- }
253
240
 
254
- .oinBadgeLink {
255
- display: inline-block;
256
- transition: opacity var(--durationS, 0.2s)
257
- var(--bezierFastoutSlowin, ease-out);
258
- }
259
-
260
- .oinBadgeLink:hover {
261
- opacity: 0.8;
262
- transform: translateY(-1px);
263
- }
264
-
265
- .oinBadgeImage {
266
- height: 40px;
267
- width: auto;
268
- border-radius: 4px;
269
- }
270
241
 
271
242
  /* Import Section */
272
243
  .importSection {
@@ -1,5 +1,5 @@
1
1
  import { type JSX, createContext, useContext } from 'react';
2
- import { classes, media } from '~/utils/style';
2
+ import { classes, media } from '~/utils/ui';
3
3
  import { themes, tokens } from './theme';
4
4
 
5
5
  interface ThemeContextType {
@@ -1,4 +1,4 @@
1
- import { pxToRem } from '~/utils/style';
1
+ import { pxToRem } from '~/utils/ui';
2
2
 
3
3
  // Full list of tokens
4
4
  const baseTokens = {
@@ -1,7 +1,7 @@
1
1
  import { useState, useEffect } from 'react';
2
2
  import { signOut } from 'firebase/auth';
3
3
  import { auth } from '~/services/firebase';
4
- import { fetchUserApi } from '~/utils/user-api-client';
4
+ import { fetchUserApi } from '~/utils/api';
5
5
  import { auditService } from '~/services/audit';
6
6
  import styles from './delete-account.module.css';
7
7
 
@@ -4,7 +4,7 @@ import { PasswordReset } from '~/routes/auth/passwordReset';
4
4
  import { DeleteAccount } from './delete-account';
5
5
  import { UserAuditViewer } from '../audit/user-audit-viewer';
6
6
  import { AuthContext } from '~/contexts/auth.context';
7
- import { getUserData, updateUserData } from '~/utils/permissions';
7
+ import { getUserData, updateUserData } from '~/utils/data';
8
8
  import { auditService } from '~/services/audit';
9
9
  import { handleAuthError, ERROR_MESSAGES } from '~/services/firebase/errors';
10
10
  import { FormField, FormButton, FormMessage } from '../form';
@@ -21,7 +21,7 @@ import {
21
21
  getPhoneDisplayValue,
22
22
  maskPhoneNumber,
23
23
  validatePhoneNumber,
24
- } from '~/utils/mfa-phone';
24
+ } from '~/utils/auth';
25
25
  import { FormButton, FormMessage } from '../form';
26
26
  import styles from './manage-profile.module.css';
27
27
 
package/app/root.tsx CHANGED
@@ -94,11 +94,6 @@ export default function App() {
94
94
  );
95
95
  }
96
96
 
97
- interface ErrorBoundaryShellProps {
98
- title: string;
99
- children: React.ReactNode;
100
- }
101
-
102
97
  const LOGIN_REDIRECT_PATH = '/';
103
98
 
104
99
  const errorActionStyle = {
@@ -133,30 +128,6 @@ async function returnToLogin() {
133
128
  }
134
129
  }
135
130
 
136
- function ErrorBoundaryShell({ title, children }: ErrorBoundaryShellProps) {
137
- return (
138
- <html lang="en" data-theme="light">
139
- <head>
140
- <meta charSet="utf-8" />
141
- <meta name="viewport" content="width=device-width, initial-scale=1" />
142
- <meta name="theme-color" content="#377087" />
143
- <meta name="color-scheme" content="light" />
144
- <style dangerouslySetInnerHTML={{ __html: themeStyles }} />
145
- <title>{title}</title>
146
- <Meta />
147
- <Links />
148
- </head>
149
- <body className="flex flex-col h-screen w-full overflow-x-hidden">
150
- <ThemeProvider theme="light" className="">
151
- <main>{children}</main>
152
- </ThemeProvider>
153
- <ScrollRestoration />
154
- <Scripts />
155
- </body>
156
- </html>
157
- );
158
- }
159
-
160
131
  export function ErrorBoundary() {
161
132
  const error = useRouteError();
162
133
 
@@ -164,27 +135,9 @@ export function ErrorBoundary() {
164
135
  const statusText = error.statusText || 'Unexpected error';
165
136
 
166
137
  return (
167
- <ErrorBoundaryShell title={`${error.status} ${statusText}`}>
168
- <div className={styles.errorContainer}>
169
- <div className={styles.errorTitle}>{error.status}</div>
170
- <p className={styles.errorMessage}>{statusText}</p>
171
- <button
172
- type="button"
173
- onClick={() => void returnToLogin()}
174
- style={errorActionStyle}
175
- className={styles.errorLink}>
176
- Return to Login
177
- </button>
178
- </div>
179
- </ErrorBoundaryShell>
180
- );
181
- }
182
-
183
- return (
184
- <ErrorBoundaryShell title="Oops! Something went wrong">
185
138
  <div className={styles.errorContainer}>
186
- <div className={styles.errorTitle}>500</div>
187
- <p className={styles.errorMessage}>Something went wrong. Please try again later.</p>
139
+ <div className={styles.errorTitle}>{error.status}</div>
140
+ <p className={styles.errorMessage}>{statusText}</p>
188
141
  <button
189
142
  type="button"
190
143
  onClick={() => void returnToLogin()}
@@ -193,6 +146,20 @@ export function ErrorBoundary() {
193
146
  Return to Login
194
147
  </button>
195
148
  </div>
196
- </ErrorBoundaryShell>
149
+ );
150
+ }
151
+
152
+ return (
153
+ <div className={styles.errorContainer}>
154
+ <div className={styles.errorTitle}>500</div>
155
+ <p className={styles.errorMessage}>Something went wrong. Please try again later.</p>
156
+ <button
157
+ type="button"
158
+ onClick={() => void returnToLogin()}
159
+ style={errorActionStyle}
160
+ className={styles.errorLink}>
161
+ Return to Login
162
+ </button>
163
+ </div>
197
164
  );
198
- }
165
+ }
@@ -8,8 +8,7 @@ import {
8
8
  } from 'firebase/auth';
9
9
  import { auth } from '~/services/firebase';
10
10
  import { handleAuthError } from '~/services/firebase/errors';
11
- import { evaluatePasswordPolicy } from '~/utils/password-policy';
12
- import { getSafeContinuePath } from '~/utils/auth-action-settings';
11
+ import { evaluatePasswordPolicy, getSafeContinuePath } from '~/utils/auth';
13
12
  import { auditService } from '~/services/audit';
14
13
  import { Icon } from '~/components/icon/icon';
15
14
  import styles from './emailActionHandler.module.css';
@@ -2,7 +2,7 @@ import { useState } from 'react';
2
2
  import { Link } from 'react-router';
3
3
  import { sendEmailVerification, type User } from 'firebase/auth';
4
4
  import { auditService } from '~/services/audit';
5
- import { buildActionCodeSettings } from '~/utils/auth-action-settings';
5
+ import { buildActionCodeSettings } from '~/utils/auth';
6
6
  import styles from './login.module.css';
7
7
 
8
8
  interface EmailVerificationProps {