@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.
- package/NOTICE +0 -5
- package/app/components/actions/case-export/core-export.ts +1 -1
- package/app/components/actions/case-export/download-handlers.ts +10 -12
- package/app/components/actions/case-export/metadata-helpers.ts +1 -1
- package/app/components/actions/case-import/confirmation-import.ts +24 -9
- package/app/components/actions/case-import/orchestrator.ts +3 -4
- package/app/components/actions/case-import/validation.ts +3 -3
- package/app/components/actions/case-import/zip-processing.ts +12 -48
- package/app/components/actions/case-manage.ts +0 -1
- package/app/components/actions/confirm-export.ts +2 -2
- package/app/components/audit/user-audit-viewer.tsx +53 -15
- package/app/components/audit/user-audit.module.css +11 -4
- package/app/components/canvas/box-annotations/box-annotations.tsx +36 -7
- package/app/components/canvas/canvas.tsx +35 -24
- package/app/components/canvas/confirmation/confirmation.module.css +5 -2
- package/app/components/canvas/confirmation/confirmation.tsx +25 -8
- package/app/components/sidebar/case-export/case-export.module.css +194 -5
- package/app/components/sidebar/case-export/case-export.tsx +291 -11
- package/app/components/sidebar/case-import/case-import.module.css +9 -5
- package/app/components/sidebar/case-import/case-import.tsx +30 -7
- package/app/components/sidebar/case-import/components/CasePreviewSection.tsx +2 -2
- package/app/components/sidebar/case-import/components/ConfirmationDialog.tsx +1 -1
- package/app/components/sidebar/case-import/components/ExistingCaseSection.tsx +1 -1
- package/app/components/sidebar/case-import/hooks/useFilePreview.ts +34 -9
- package/app/components/sidebar/cases/case-sidebar.tsx +13 -13
- package/app/components/sidebar/cases/cases-modal.tsx +12 -2
- package/app/components/sidebar/files/files-modal.tsx +28 -8
- package/app/components/sidebar/sidebar.module.css +2 -3
- package/app/components/sidebar/sidebar.tsx +1 -16
- package/app/components/sidebar/upload/image-upload-zone.tsx +4 -4
- package/app/components/toolbar/toolbar-color-selector.module.css +2 -2
- package/app/components/toolbar/toolbar-color-selector.tsx +3 -3
- package/app/components/toolbar/toolbar.tsx +19 -9
- package/app/components/user/delete-account.module.css +4 -1
- package/app/components/user/delete-account.tsx +22 -3
- package/app/components/user/manage-profile.tsx +0 -2
- package/app/entry.server.tsx +2 -3
- package/app/hooks/useInactivityTimeout.ts +5 -1
- package/app/root.tsx +0 -3
- package/app/routes/_index.tsx +1 -16
- package/app/routes/auth/emailVerification.tsx +1 -1
- package/app/routes/auth/login.tsx +7 -5
- package/app/routes/auth/route.ts +3 -12
- package/app/routes/striae/striae.tsx +1 -1
- package/app/services/audit.service.ts +29 -9
- package/app/tailwind.css +16 -1
- package/app/types/audit.ts +3 -3
- package/app/types/case.ts +1 -1
- package/app/types/import.ts +0 -2
- package/app/utils/SHA256.ts +3 -3
- package/app/utils/batch-operations.ts +6 -6
- package/app/utils/data-operations.ts +14 -7
- package/app/utils/permissions.ts +0 -2
- package/functions/[[path]].ts +0 -1
- package/package.json +1 -2
- package/public/_headers +0 -12
- package/public/assets/striae.jpg +0 -0
- package/scripts/deploy-config.sh +0 -7
- package/scripts/run-eslint.cjs +14 -6
- package/worker-configuration.d.ts +2 -2
- package/workers/audit-worker/src/audit-worker.example.ts +9 -7
- package/workers/audit-worker/worker-configuration.d.ts +2 -2
- package/workers/audit-worker/wrangler.jsonc.example +1 -1
- package/workers/data-worker/src/data-worker.example.ts +1 -1
- package/workers/data-worker/worker-configuration.d.ts +2 -2
- package/workers/data-worker/wrangler.jsonc.example +1 -1
- package/workers/image-worker/worker-configuration.d.ts +2 -2
- package/workers/image-worker/wrangler.jsonc.example +1 -1
- package/workers/keys-worker/worker-configuration.d.ts +2 -2
- package/workers/keys-worker/wrangler.jsonc.example +1 -1
- package/workers/pdf-worker/src/pdf-worker.example.ts +3 -3
- package/workers/pdf-worker/worker-configuration.d.ts +7448 -7448
- package/workers/pdf-worker/wrangler.jsonc.example +1 -1
- package/workers/user-worker/src/user-worker.example.ts +10 -10
- package/workers/user-worker/worker-configuration.d.ts +2 -2
- package/workers/user-worker/wrangler.jsonc.example +1 -1
- package/wrangler.toml.example +1 -1
- package/app/components/sidebar/hash/hash-utility.module.css +0 -366
- package/app/components/sidebar/hash/hash-utility.tsx +0 -982
- package/app/config-example/meta-config.json +0 -6
- package/app/routes/mobile-prevented/mobilePrevented.module.css +0 -47
- package/app/routes/mobile-prevented/mobilePrevented.tsx +0 -26
- package/app/routes/mobile-prevented/route.ts +0 -14
- package/app/utils/device-detection.ts +0 -5
- package/app/utils/html-sanitizer.ts +0 -80
- package/app/utils/meta.ts +0 -48
- package/public/icon-256.png +0 -0
- package/public/icon-512.png +0 -0
- package/public/manifest.json +0 -25
- package/public/shortcut.png +0 -0
- package/public/social-image.png +0 -0
|
@@ -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: '<script>alert("xss")</script>'
|
|
24
|
-
*
|
|
25
|
-
* escapeHtml('John & Jane <test@example.com>')
|
|
26
|
-
* // Returns: 'John & Jane <test@example.com>'
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
export function escapeHtml(text: string | null | undefined): string {
|
|
30
|
-
if (!text) return '';
|
|
31
|
-
|
|
32
|
-
return String(text)
|
|
33
|
-
.replace(/&/g, '&')
|
|
34
|
-
.replace(/</g, '<')
|
|
35
|
-
.replace(/>/g, '>')
|
|
36
|
-
.replace(/"/g, '"')
|
|
37
|
-
.replace(/'/g, ''')
|
|
38
|
-
.replace(/\//g, '/');
|
|
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: '<script>alert("xss")</script>',
|
|
61
|
-
* // email: 'test@example.com',
|
|
62
|
-
* // company: 'ACME & 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
|
-
}
|
package/public/icon-256.png
DELETED
|
Binary file
|
package/public/icon-512.png
DELETED
|
Binary file
|
package/public/manifest.json
DELETED
|
@@ -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
|
-
}
|
package/public/shortcut.png
DELETED
|
Binary file
|
package/public/social-image.png
DELETED
|
Binary file
|