@striae-org/striae 3.0.4 → 3.1.0

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 (91) hide show
  1. package/NOTICE +0 -5
  2. package/app/components/actions/case-export/core-export.ts +1 -1
  3. package/app/components/actions/case-export/download-handlers.ts +10 -12
  4. package/app/components/actions/case-export/metadata-helpers.ts +1 -1
  5. package/app/components/actions/case-import/confirmation-import.ts +24 -9
  6. package/app/components/actions/case-import/orchestrator.ts +3 -4
  7. package/app/components/actions/case-import/validation.ts +3 -3
  8. package/app/components/actions/case-import/zip-processing.ts +12 -48
  9. package/app/components/actions/case-manage.ts +0 -1
  10. package/app/components/actions/confirm-export.ts +2 -2
  11. package/app/components/audit/user-audit-viewer.tsx +53 -15
  12. package/app/components/audit/user-audit.module.css +11 -4
  13. package/app/components/canvas/box-annotations/box-annotations.tsx +36 -7
  14. package/app/components/canvas/canvas.tsx +35 -24
  15. package/app/components/canvas/confirmation/confirmation.module.css +5 -2
  16. package/app/components/canvas/confirmation/confirmation.tsx +25 -8
  17. package/app/components/sidebar/case-export/case-export.module.css +194 -5
  18. package/app/components/sidebar/case-export/case-export.tsx +291 -11
  19. package/app/components/sidebar/case-import/case-import.module.css +9 -5
  20. package/app/components/sidebar/case-import/case-import.tsx +30 -7
  21. package/app/components/sidebar/case-import/components/CasePreviewSection.tsx +2 -2
  22. package/app/components/sidebar/case-import/components/ConfirmationDialog.tsx +1 -1
  23. package/app/components/sidebar/case-import/components/ExistingCaseSection.tsx +1 -1
  24. package/app/components/sidebar/case-import/hooks/useFilePreview.ts +34 -9
  25. package/app/components/sidebar/cases/case-sidebar.tsx +13 -13
  26. package/app/components/sidebar/cases/cases-modal.tsx +12 -2
  27. package/app/components/sidebar/files/files-modal.tsx +28 -8
  28. package/app/components/sidebar/sidebar.module.css +2 -3
  29. package/app/components/sidebar/sidebar.tsx +1 -16
  30. package/app/components/sidebar/upload/image-upload-zone.tsx +4 -4
  31. package/app/components/toolbar/toolbar-color-selector.module.css +2 -2
  32. package/app/components/toolbar/toolbar-color-selector.tsx +3 -3
  33. package/app/components/toolbar/toolbar.tsx +19 -9
  34. package/app/components/user/delete-account.module.css +4 -1
  35. package/app/components/user/delete-account.tsx +22 -3
  36. package/app/components/user/manage-profile.tsx +0 -2
  37. package/app/entry.server.tsx +2 -3
  38. package/app/hooks/useInactivityTimeout.ts +5 -1
  39. package/app/root.tsx +0 -3
  40. package/app/routes/_index.tsx +1 -16
  41. package/app/routes/auth/emailVerification.tsx +1 -1
  42. package/app/routes/auth/login.tsx +7 -5
  43. package/app/routes/auth/route.ts +3 -12
  44. package/app/routes/striae/striae.tsx +1 -1
  45. package/app/services/audit.service.ts +29 -9
  46. package/app/tailwind.css +16 -1
  47. package/app/types/audit.ts +3 -3
  48. package/app/types/case.ts +1 -1
  49. package/app/types/import.ts +0 -2
  50. package/app/utils/SHA256.ts +3 -3
  51. package/app/utils/batch-operations.ts +6 -6
  52. package/app/utils/data-operations.ts +14 -7
  53. package/app/utils/permissions.ts +0 -2
  54. package/functions/[[path]].ts +0 -1
  55. package/package.json +1 -2
  56. package/public/_headers +0 -12
  57. package/public/assets/striae.jpg +0 -0
  58. package/scripts/deploy-config.sh +0 -7
  59. package/scripts/run-eslint.cjs +14 -6
  60. package/worker-configuration.d.ts +2 -2
  61. package/workers/audit-worker/src/audit-worker.example.ts +9 -7
  62. package/workers/audit-worker/worker-configuration.d.ts +2 -2
  63. package/workers/audit-worker/wrangler.jsonc.example +1 -1
  64. package/workers/data-worker/src/data-worker.example.ts +1 -1
  65. package/workers/data-worker/worker-configuration.d.ts +2 -2
  66. package/workers/data-worker/wrangler.jsonc.example +1 -1
  67. package/workers/image-worker/worker-configuration.d.ts +2 -2
  68. package/workers/image-worker/wrangler.jsonc.example +1 -1
  69. package/workers/keys-worker/worker-configuration.d.ts +2 -2
  70. package/workers/keys-worker/wrangler.jsonc.example +1 -1
  71. package/workers/pdf-worker/src/pdf-worker.example.ts +3 -3
  72. package/workers/pdf-worker/worker-configuration.d.ts +7448 -7448
  73. package/workers/pdf-worker/wrangler.jsonc.example +1 -1
  74. package/workers/user-worker/src/user-worker.example.ts +10 -10
  75. package/workers/user-worker/worker-configuration.d.ts +2 -2
  76. package/workers/user-worker/wrangler.jsonc.example +1 -1
  77. package/wrangler.toml.example +1 -1
  78. package/app/components/sidebar/hash/hash-utility.module.css +0 -366
  79. package/app/components/sidebar/hash/hash-utility.tsx +0 -982
  80. package/app/config-example/meta-config.json +0 -6
  81. package/app/routes/mobile-prevented/mobilePrevented.module.css +0 -47
  82. package/app/routes/mobile-prevented/mobilePrevented.tsx +0 -26
  83. package/app/routes/mobile-prevented/route.ts +0 -14
  84. package/app/utils/device-detection.ts +0 -5
  85. package/app/utils/html-sanitizer.ts +0 -80
  86. package/app/utils/meta.ts +0 -48
  87. package/public/icon-256.png +0 -0
  88. package/public/icon-512.png +0 -0
  89. package/public/manifest.json +0 -25
  90. package/public/shortcut.png +0 -0
  91. package/public/social-image.png +0 -0
@@ -1,6 +0,0 @@
1
- {
2
- "name": "Striae",
3
- "author": "Stephen J. Lu",
4
- "title": "A Firearms Examiner's Comparison Companion",
5
- "url": "PAGES_CUSTOM_DOMAIN"
6
- }
@@ -1,47 +0,0 @@
1
- .container {
2
- min-height: 100vh;
3
- display: flex;
4
- align-items: center;
5
- justify-content: center;
6
- padding: var(--spaceL);
7
- }
8
-
9
- .card {
10
- width: 100%;
11
- max-width: var(--maxWidthS);
12
- background-color: color-mix(in lab, var(--backgroundLight) 95%, transparent);
13
- border-radius: var(--spaceXS);
14
- padding: var(--space2XL);
15
- box-shadow: 0 var(--spaceXS) var(--spaceM) color-mix(in lab, var(--black) 10%, transparent);
16
- text-align: center;
17
- }
18
-
19
- .title {
20
- margin: 0 0 var(--spaceM);
21
- color: var(--textTitle);
22
- font-size: var(--fontSizeH4);
23
- }
24
-
25
- .description {
26
- margin: 0 0 var(--spaceXL);
27
- color: var(--textBody);
28
- font-size: var(--fontSizeBodyM);
29
- line-height: 1.6;
30
- }
31
-
32
- .link {
33
- display: inline-flex;
34
- align-items: center;
35
- justify-content: center;
36
- text-decoration: none;
37
- background-color: var(--primary);
38
- color: var(--white);
39
- border-radius: var(--spaceXS);
40
- padding: var(--spaceM) var(--spaceL);
41
- font-size: var(--fontSizeBodyS);
42
- transition: background-color var(--durationS) var(--bezierFastoutSlowin);
43
- }
44
-
45
- .link:hover {
46
- background-color: color-mix(in lab, var(--primary) 85%, var(--black));
47
- }
@@ -1,26 +0,0 @@
1
- import { Link } from '@remix-run/react';
2
- import { baseMeta } from '~/utils/meta';
3
- import styles from './mobilePrevented.module.css';
4
-
5
- export const meta = () => {
6
- return baseMeta({
7
- title: 'Desktop Required',
8
- description: 'Striae authentication is available on desktop devices only.',
9
- });
10
- };
11
-
12
- export const MobilePrevented = () => {
13
- return (
14
- <div className={styles.container}>
15
- <div className={styles.card}>
16
- <h1 className={styles.title}>Desktop Required</h1>
17
- <p className={styles.description}>
18
- Striae authentication is restricted to desktop devices. Please open this page on a desktop or laptop computer to continue.
19
- </p>
20
- <Link viewTransition prefetch="intent" to="https://striae.org" className={styles.link}>
21
- Return Home
22
- </Link>
23
- </div>
24
- </div>
25
- );
26
- };
@@ -1,14 +0,0 @@
1
- import { redirect, type LoaderFunctionArgs } from '@remix-run/cloudflare';
2
- import { isMobileOrTabletUserAgent } from '~/utils/device-detection';
3
-
4
- export const loader = async ({ request }: LoaderFunctionArgs) => {
5
- const userAgent = request.headers.get('user-agent') ?? '';
6
-
7
- if (!isMobileOrTabletUserAgent(userAgent)) {
8
- throw redirect('/');
9
- }
10
-
11
- return null;
12
- };
13
-
14
- export { MobilePrevented as default, meta } from './mobilePrevented';
@@ -1,5 +0,0 @@
1
- const mobileOrTabletUserAgentPattern = /mobile|android|iphone|ipad|ipod|blackberry|iemobile|opera mini|tablet|silk|kindle|playbook|webos|windows phone/i;
2
-
3
- export const isMobileOrTabletUserAgent = (userAgent: string): boolean => {
4
- return mobileOrTabletUserAgentPattern.test(userAgent);
5
- };
@@ -1,80 +0,0 @@
1
- /**
2
- * HTML Sanitization Utility
3
- *
4
- * Provides secure HTML escaping for user-generated content
5
- * embedded in email templates and other HTML contexts.
6
- *
7
- * @module html-sanitizer
8
- */
9
-
10
- /**
11
- * Escapes HTML special characters to prevent injection attacks
12
- *
13
- * Converts characters that have special meaning in HTML into their
14
- * HTML entity equivalents to ensure they are rendered as text rather
15
- * than interpreted as markup.
16
- *
17
- * @param text - Raw user input that may contain HTML characters
18
- * @returns Safely escaped string suitable for embedding in HTML
19
- *
20
- * @example
21
- * ```typescript
22
- * escapeHtml('<script>alert("xss")</script>')
23
- * // Returns: '&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;'
24
- *
25
- * escapeHtml('John & Jane <test@example.com>')
26
- * // Returns: 'John &amp; Jane &lt;test@example.com&gt;'
27
- * ```
28
- */
29
- export function escapeHtml(text: string | null | undefined): string {
30
- if (!text) return '';
31
-
32
- return String(text)
33
- .replace(/&/g, '&amp;')
34
- .replace(/</g, '&lt;')
35
- .replace(/>/g, '&gt;')
36
- .replace(/"/g, '&quot;')
37
- .replace(/'/g, '&#x27;')
38
- .replace(/\//g, '&#x2F;');
39
- }
40
-
41
- /**
42
- * Escapes multiple string values for safe HTML embedding
43
- *
44
- * Convenience function for escaping an object of string values.
45
- * Useful when preparing multiple user inputs for email templates.
46
- *
47
- * @param values - Object containing string values to escape
48
- * @returns New object with all string values HTML-escaped
49
- *
50
- * @example
51
- * ```typescript
52
- * const userInput = {
53
- * name: '<script>alert("xss")</script>',
54
- * email: 'test@example.com',
55
- * company: 'ACME & Co.'
56
- * };
57
- *
58
- * const safe = escapeHtmlObject(userInput);
59
- * // Returns: {
60
- * // name: '&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;',
61
- * // email: 'test@example.com',
62
- * // company: 'ACME &amp; Co.'
63
- * // }
64
- * ```
65
- */
66
- export function escapeHtmlObject<T extends Record<string, any>>(
67
- values: T
68
- ): T {
69
- const escaped = {} as T;
70
-
71
- for (const [key, value] of Object.entries(values)) {
72
- if (typeof value === 'string') {
73
- escaped[key as keyof T] = escapeHtml(value) as T[keyof T];
74
- } else {
75
- escaped[key as keyof T] = value;
76
- }
77
- }
78
-
79
- return escaped;
80
- }
package/app/utils/meta.ts DELETED
@@ -1,48 +0,0 @@
1
- import config from '~/config/meta-config.json';
2
-
3
- interface AppConfig {
4
- name: string;
5
- author: string;
6
- title: string;
7
- url: string;
8
- }
9
-
10
- const { name, author, url } = config as AppConfig;
11
- const defaultOgImage = `${url}/social-image.png`;
12
-
13
-
14
- interface MetaParams {
15
- title: string;
16
- description: string;
17
- prefix?: string;
18
- ogImage?: string;
19
- }
20
-
21
- export function baseMeta({
22
- title: pageTitle,
23
- description,
24
- ogImage = defaultOgImage,
25
- }: MetaParams) {
26
- const titleText = `${name} | ${pageTitle}`;
27
-
28
- return [
29
- { title: titleText },
30
- { name: 'description', content: description },
31
- { name: 'author', content: author },
32
- { property: 'og:image', content: ogImage },
33
- { property: 'og:image:alt', content: 'Banner for the site' },
34
- { property: 'og:image:width', content: '1020' },
35
- { property: 'og:image:height', content: '484' },
36
- { property: 'og:title', content: titleText },
37
- { property: 'og:site_name', content: name },
38
- { property: 'og:type', content: 'website' },
39
- { property: 'og:url', content: url },
40
- { property: 'og:description', content: description },
41
- { property: 'twitter:card', content: 'summary_large_image' },
42
- { property: 'twitter:description', content: description },
43
- { property: 'twitter:title', content: titleText },
44
- { property: 'twitter:site', content: url },
45
- { property: 'twitter:creator', content: author },
46
- { property: 'twitter:image', content: ogImage },
47
- ];
48
- }
Binary file
Binary file
@@ -1,25 +0,0 @@
1
- {
2
- "short_name": "Striae",
3
- "name": "Striae: A Firearms Examiner's Comparison Companion",
4
- "icons": [
5
- {
6
- "src": "shortcut.png",
7
- "sizes": "64x64",
8
- "type": "image/png"
9
- },
10
- {
11
- "src": "icon-256.png",
12
- "sizes": "256x256",
13
- "type": "image/png"
14
- },
15
- {
16
- "src": "icon-512.png",
17
- "sizes": "512x512",
18
- "type": "image/png"
19
- }
20
- ],
21
- "start_url": ".",
22
- "display": "standalone",
23
- "theme_color": "#ddd",
24
- "background_color": "#ddd"
25
- }
Binary file
Binary file