create-safest-tools 0.2.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/LICENSE +201 -0
- package/README.md +71 -0
- package/bin/create-safest-tools.mjs +12 -0
- package/package.json +34 -0
- package/src/cli.mjs +128 -0
- package/src/config.mjs +151 -0
- package/src/scaffold.mjs +30 -0
- package/template/LICENSE +201 -0
- package/template/README.md +35 -0
- package/template/console/README.md +28 -0
- package/template/console/analytics/AnalyticsWorkspace.tsx +55 -0
- package/template/console/analytics/controller.ts +133 -0
- package/template/console/analytics/events.ts +33 -0
- package/template/console/analytics/store.ts +33 -0
- package/template/console/analytics/types.ts +38 -0
- package/template/console/appeals/AppealWorkspace.tsx +73 -0
- package/template/console/appeals/controller.ts +125 -0
- package/template/console/appeals/events.ts +33 -0
- package/template/console/appeals/store.ts +35 -0
- package/template/console/appeals/types.ts +37 -0
- package/template/console/assistant/AssistantWorkspace.tsx +133 -0
- package/template/console/assistant/types.ts +34 -0
- package/template/console/auth/AccountJourney.tsx +69 -0
- package/template/console/auth/InvitationAcceptance.tsx +145 -0
- package/template/console/auth/OAuthButtons.tsx +78 -0
- package/template/console/auth/OperatorLogin.tsx +110 -0
- package/template/console/auth/PasswordRecovery.tsx +132 -0
- package/template/console/auth/account-route.ts +15 -0
- package/template/console/auth/browser-navigation.ts +7 -0
- package/template/console/auth/events.ts +15 -0
- package/template/console/command/CommandCentre.tsx +119 -0
- package/template/console/command/controller.ts +267 -0
- package/template/console/command/events.ts +19 -0
- package/template/console/command/store.ts +36 -0
- package/template/console/command/types.ts +61 -0
- package/template/console/components/AnalystIdentity.tsx +25 -0
- package/template/console/components/PageHeader.tsx +27 -0
- package/template/console/configuration/ConfigurationDialog.tsx +200 -0
- package/template/console/configuration/ConfigurationWorkspace.tsx +66 -0
- package/template/console/configuration/FormBuilder.tsx +143 -0
- package/template/console/configuration/api.ts +40 -0
- package/template/console/configuration/events.ts +14 -0
- package/template/console/configuration/types.ts +79 -0
- package/template/console/lib/format.ts +49 -0
- package/template/console/lib/http.ts +96 -0
- package/template/console/main.tsx +225 -0
- package/template/console/operations/OperationsWorkspace.tsx +126 -0
- package/template/console/operations/controller.ts +237 -0
- package/template/console/operations/events.ts +37 -0
- package/template/console/operations/store.ts +32 -0
- package/template/console/operations/types.ts +107 -0
- package/template/console/people/PeopleWorkspace.tsx +81 -0
- package/template/console/people/types.ts +25 -0
- package/template/console/profile/ProfileWorkspace.tsx +136 -0
- package/template/console/profile/events.ts +9 -0
- package/template/console/profile/types.ts +6 -0
- package/template/console/quality/QualityWorkspace.tsx +87 -0
- package/template/console/quality/controller.ts +154 -0
- package/template/console/quality/events.ts +34 -0
- package/template/console/quality/store.ts +36 -0
- package/template/console/quality/types.ts +70 -0
- package/template/console/queues/QueueEditor.tsx +173 -0
- package/template/console/queues/QueueWorkspace.tsx +109 -0
- package/template/console/queues/controller.ts +194 -0
- package/template/console/queues/events.ts +34 -0
- package/template/console/queues/store.ts +37 -0
- package/template/console/queues/types.ts +102 -0
- package/template/console/registry/RegistryDialog.tsx +198 -0
- package/template/console/registry/RegistryWorkspace.tsx +108 -0
- package/template/console/registry/events.ts +14 -0
- package/template/console/registry/types.ts +52 -0
- package/template/console/reports/ReportDrawer.tsx +159 -0
- package/template/console/reports/ReportWorkspace.tsx +90 -0
- package/template/console/reports/controller.ts +517 -0
- package/template/console/reports/events.ts +42 -0
- package/template/console/reports/store.ts +39 -0
- package/template/console/reports/types.ts +230 -0
- package/template/console/settings/BrandEditor.tsx +126 -0
- package/template/console/settings/ChannelDialog.tsx +241 -0
- package/template/console/settings/SettingsWorkspace.tsx +155 -0
- package/template/console/settings/events.ts +19 -0
- package/template/console/settings/handoff.ts +22 -0
- package/template/console/settings/types.ts +93 -0
- package/template/console/shell/WorkspaceShell.tsx +160 -0
- package/template/console/shell/controller.ts +182 -0
- package/template/console/shell/events.ts +25 -0
- package/template/console/shell/navigation.ts +61 -0
- package/template/console/shell/store.ts +56 -0
- package/template/console/shell/types.ts +86 -0
- package/template/console/workflows/CreateWorkflowDialog.tsx +87 -0
- package/template/console/workflows/WorkflowCanvas.tsx +42 -0
- package/template/console/workflows/WorkflowDialogs.tsx +6 -0
- package/template/console/workflows/WorkflowStudio.tsx +331 -0
- package/template/console/workflows/WorkflowWorkspace.tsx +82 -0
- package/template/console/workflows/events.ts +17 -0
- package/template/console/workflows/graph.ts +156 -0
- package/template/console/workflows/templates.ts +70 -0
- package/template/console/workflows/types.ts +201 -0
- package/template/gitignore.template +18 -0
- package/template/migrations/0001_reports_foundation.sql +444 -0
- package/template/migrations/0002_human_report_loop.sql +65 -0
- package/template/migrations/0003_delivery_reliability.sql +18 -0
- package/template/migrations/0004_public_intake.sql +14 -0
- package/template/migrations/0005_operations_visibility.sql +24 -0
- package/template/migrations/0006_ai_governance.sql +198 -0
- package/template/migrations/0007_ai_release_gates.sql +6 -0
- package/template/migrations/0008_retention_analytics_exports.sql +52 -0
- package/template/migrations/0009_retention_derived_copies.sql +14 -0
- package/template/migrations/0010_ai_quality_controls.sql +26 -0
- package/template/migrations/0011_analyst_presence.sql +28 -0
- package/template/migrations/0012_queue_policies.sql +87 -0
- package/template/migrations/0013_routing_agents.sql +63 -0
- package/template/migrations/0014_webhook_enrichments.sql +122 -0
- package/template/migrations/0015_queue_owned_ai.sql +55 -0
- package/template/migrations/0016_operator_accounts.sql +67 -0
- package/template/migrations/0017_operator_profiles_and_recovery.sql +33 -0
- package/template/migrations/0018_platform_configuration.sql +382 -0
- package/template/migrations/0019_workflow_authoring_runtime.sql +372 -0
- package/template/migrations/0020_tasks_findings_assistant_budgets.sql +427 -0
- package/template/migrations/0021_abuse_evidence_operations.sql +324 -0
- package/template/migrations/0022_workflow_dispatch_operations.sql +42 -0
- package/template/migrations/0023_component_connection_execution.sql +75 -0
- package/template/migrations/0024_access_runtime_integrity.sql +72 -0
- package/template/migrations/0025_installation_timezone.sql +11 -0
- package/template/migrations/0026_ai_and_egress_execution_controls.sql +49 -0
- package/template/migrations/0027_prompt_and_ai_registry.sql +37 -0
- package/template/migrations/0028_step_attempt_ai_provenance.sql +13 -0
- package/template/migrations/0029_evidence_fetch_transport.sql +5 -0
- package/template/migrations/0030_evidence_dlq_incidents.sql +45 -0
- package/template/migrations/0031_shadow_quality_integrity.sql +7 -0
- package/template/migrations/0032_action_delivery_outbox.sql +55 -0
- package/template/migrations/0033_configuration_and_assistant_drafts.sql +43 -0
- package/template/migrations/0034_installation_integrations.sql +31 -0
- package/template/migrations/0035_workspace_governance.sql +21 -0
- package/template/migrations/0036_published_routing_baseline.sql +15 -0
- package/template/migrations/0037_builtin_phishing_specialist.sql +71 -0
- package/template/migrations/0038_remove_deprecated_enrichment_runtime.sql +228 -0
- package/template/migrations/0039_secure_reporting_channels.sql +45 -0
- package/template/migrations/0040_notification_only_reporting.sql +24 -0
- package/template/migrations/0041_better_auth_credentials.sql +17 -0
- package/template/package.json +47 -0
- package/template/public/_headers +27 -0
- package/template/public/app-icon-192.png +0 -0
- package/template/public/app-icon-512.png +0 -0
- package/template/public/brand-icon.svg +7 -0
- package/template/public/brand-tokens.css +80 -0
- package/template/public/console/auth-shell.js +19340 -0
- package/template/public/customer-brand.js +58 -0
- package/template/public/embed/embed.css +139 -0
- package/template/public/embed/embed.js +408 -0
- package/template/public/embed/index.html +91 -0
- package/template/public/favicon.svg +7 -0
- package/template/public/fonts/Manrope-Variable.ttf +0 -0
- package/template/public/fonts/Newsreader-Italic-Variable.ttf +0 -0
- package/template/public/fonts/Newsreader-Variable.ttf +0 -0
- package/template/public/index.html +123 -0
- package/template/public/logo-primary.svg +7 -0
- package/template/public/logo-reversed.svg +7 -0
- package/template/public/manifest.webmanifest +21 -0
- package/template/public/public-report.js +184 -0
- package/template/public/report/index.html +39 -0
- package/template/public/report/public-report.css +20 -0
- package/template/public/social-card.png +0 -0
- package/template/public/styles.css +1521 -0
- package/template/public/widget.css +80 -0
- package/template/public/widget.js +220 -0
- package/template/reports.config.example.json +38 -0
- package/template/reports.schema.json +89 -0
- package/template/scripts/reports-auth-onboarding.mjs +180 -0
- package/template/scripts/reports-backup.mjs +276 -0
- package/template/scripts/reports-cloudflare-preflight.mjs +152 -0
- package/template/scripts/reports-deploy.mjs +173 -0
- package/template/scripts/reports-plan.mjs +226 -0
- package/template/scripts/reports-restore.mjs +180 -0
- package/template/scripts/reports-secrets.mjs +73 -0
- package/template/scripts/reports-uninstall-plan.mjs +32 -0
- package/template/src/agent-executor.ts +330 -0
- package/template/src/ai-observability.ts +163 -0
- package/template/src/ai-registry-validation.ts +244 -0
- package/template/src/ai-registry.ts +292 -0
- package/template/src/api-cursor.ts +84 -0
- package/template/src/assistant.ts +554 -0
- package/template/src/audit.ts +39 -0
- package/template/src/backup-service.ts +269 -0
- package/template/src/budget-control.ts +127 -0
- package/template/src/component-executor.ts +845 -0
- package/template/src/configuration-registry.ts +550 -0
- package/template/src/connection-egress.ts +430 -0
- package/template/src/connection-oauth.ts +368 -0
- package/template/src/evidence-service.ts +335 -0
- package/template/src/human-tasks.ts +316 -0
- package/template/src/index.ts +4114 -0
- package/template/src/installation-admin.ts +301 -0
- package/template/src/intake-abuse.ts +156 -0
- package/template/src/platform-registry-validation.ts +367 -0
- package/template/src/platform-registry.ts +753 -0
- package/template/src/report-admin.ts +342 -0
- package/template/src/report-ai-quality.ts +390 -0
- package/template/src/report-ai-validation.ts +80 -0
- package/template/src/report-ai.ts +857 -0
- package/template/src/report-auth.ts +292 -0
- package/template/src/report-better-auth.ts +583 -0
- package/template/src/report-context-schema.ts +132 -0
- package/template/src/report-context.ts +126 -0
- package/template/src/report-crypto.ts +142 -0
- package/template/src/report-delivery.ts +579 -0
- package/template/src/report-form-validation.ts +51 -0
- package/template/src/report-governance.ts +510 -0
- package/template/src/report-http.ts +90 -0
- package/template/src/report-operations.ts +685 -0
- package/template/src/report-operator-accounts.ts +810 -0
- package/template/src/report-presence.ts +398 -0
- package/template/src/report-queue-validation.ts +309 -0
- package/template/src/report-queues.ts +478 -0
- package/template/src/report-repository.ts +972 -0
- package/template/src/report-router-agent.ts +328 -0
- package/template/src/report-router-validation.ts +81 -0
- package/template/src/report-routing.ts +178 -0
- package/template/src/report-turnstile.ts +142 -0
- package/template/src/report-types.ts +224 -0
- package/template/src/report-validation.ts +279 -0
- package/template/src/report-workflow-validation.ts +119 -0
- package/template/src/report-workflow.ts +886 -0
- package/template/src/shadow-quality.ts +278 -0
- package/template/src/workflow-actions.ts +782 -0
- package/template/src/workflow-compiler.ts +230 -0
- package/template/src/workflow-dynamic-runtime.ts +613 -0
- package/template/src/workflow-effects.ts +316 -0
- package/template/src/workflow-expressions.ts +191 -0
- package/template/src/workflow-platform-types.ts +121 -0
- package/template/src/workflow-platform-validation.ts +540 -0
- package/template/src/workflow-repository.ts +916 -0
- package/template/src/workflow-runs.ts +686 -0
- package/template/src/workflow-simulator.ts +211 -0
- package/template/src/workspace-branding.ts +128 -0
- package/template/src/workspace-governance.ts +279 -0
- package/template/tsconfig.console.json +23 -0
- package/template/tsconfig.json +22 -0
- package/template/vite.console.config.ts +20 -0
- package/template/worker-configuration.d.ts +65 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
ALTER TABLE action_proposals ADD COLUMN delivery_attempt_count INTEGER NOT NULL DEFAULT 0 CHECK (delivery_attempt_count >= 0);
|
|
4
|
+
ALTER TABLE action_proposals ADD COLUMN next_attempt_at TEXT;
|
|
5
|
+
ALTER TABLE action_proposals ADD COLUMN lease_expires_at TEXT;
|
|
6
|
+
ALTER TABLE action_proposals ADD COLUMN last_error_code TEXT;
|
|
7
|
+
ALTER TABLE action_proposals ADD COLUMN delivery_terminal INTEGER NOT NULL DEFAULT 0 CHECK (delivery_terminal IN (0, 1));
|
|
8
|
+
|
|
9
|
+
CREATE INDEX action_proposals_delivery_due_idx
|
|
10
|
+
ON action_proposals(state, delivery_terminal, next_attempt_at, id);
|
|
11
|
+
|
|
12
|
+
ALTER TABLE dead_letter_items RENAME TO dead_letter_items_v5;
|
|
13
|
+
|
|
14
|
+
CREATE TABLE dead_letter_items (
|
|
15
|
+
id TEXT PRIMARY KEY,
|
|
16
|
+
fingerprint TEXT NOT NULL UNIQUE,
|
|
17
|
+
source_queue TEXT NOT NULL,
|
|
18
|
+
source_message_id TEXT NOT NULL,
|
|
19
|
+
job_type TEXT NOT NULL CHECK (job_type IN (
|
|
20
|
+
'route_report', 'process_ai_report', 'run_enrichment', 'fetch_evidence',
|
|
21
|
+
'dispatch_workflow', 'deliver_action', 'deliver_notification', 'deliver_email',
|
|
22
|
+
'apply_action_proposal', 'invalid'
|
|
23
|
+
)),
|
|
24
|
+
job_id TEXT,
|
|
25
|
+
report_id TEXT REFERENCES reports(id),
|
|
26
|
+
outbox_id TEXT,
|
|
27
|
+
incident_id TEXT REFERENCES operations_incidents(id) ON DELETE SET NULL,
|
|
28
|
+
state TEXT NOT NULL DEFAULT 'open' CHECK (state IN ('open', 'acknowledged', 'resolved')),
|
|
29
|
+
error_code TEXT NOT NULL,
|
|
30
|
+
occurrence_count INTEGER NOT NULL DEFAULT 1 CHECK (occurrence_count > 0),
|
|
31
|
+
details_json TEXT NOT NULL DEFAULT '{}',
|
|
32
|
+
first_seen_at TEXT NOT NULL,
|
|
33
|
+
last_seen_at TEXT NOT NULL,
|
|
34
|
+
resolved_at TEXT
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
INSERT INTO dead_letter_items (
|
|
38
|
+
id, fingerprint, source_queue, source_message_id, job_type, job_id,
|
|
39
|
+
report_id, outbox_id, incident_id, state, error_code, occurrence_count,
|
|
40
|
+
details_json, first_seen_at, last_seen_at, resolved_at
|
|
41
|
+
)
|
|
42
|
+
SELECT
|
|
43
|
+
id, fingerprint, source_queue, source_message_id, job_type, job_id,
|
|
44
|
+
report_id, outbox_id, incident_id, state, error_code, occurrence_count,
|
|
45
|
+
details_json, first_seen_at, last_seen_at, resolved_at
|
|
46
|
+
FROM dead_letter_items_v5;
|
|
47
|
+
|
|
48
|
+
DROP TABLE dead_letter_items_v5;
|
|
49
|
+
|
|
50
|
+
CREATE INDEX dead_letter_items_state_idx
|
|
51
|
+
ON dead_letter_items(state, last_seen_at DESC, id DESC);
|
|
52
|
+
CREATE INDEX dead_letter_items_report_idx
|
|
53
|
+
ON dead_letter_items(report_id, last_seen_at DESC, id DESC);
|
|
54
|
+
CREATE INDEX dead_letter_items_incident_idx
|
|
55
|
+
ON dead_letter_items(incident_id, state, last_seen_at DESC, id DESC);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
CREATE TABLE configuration_drafts (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
installation_id TEXT NOT NULL REFERENCES installations(id) ON DELETE CASCADE,
|
|
6
|
+
configuration_type TEXT NOT NULL CHECK (configuration_type IN ('form', 'policy', 'template', 'routing_rules')),
|
|
7
|
+
configuration_key TEXT NOT NULL,
|
|
8
|
+
content_json TEXT NOT NULL,
|
|
9
|
+
content_digest TEXT NOT NULL,
|
|
10
|
+
validation_json TEXT NOT NULL DEFAULT '{"valid":false,"errors":[{"code":"not_validated"}]}',
|
|
11
|
+
validation_status TEXT NOT NULL DEFAULT 'not_validated' CHECK (validation_status IN ('not_validated', 'valid', 'invalid')),
|
|
12
|
+
revision INTEGER NOT NULL DEFAULT 1 CHECK (revision >= 1),
|
|
13
|
+
last_published_version_id TEXT,
|
|
14
|
+
created_by TEXT NOT NULL,
|
|
15
|
+
updated_by TEXT NOT NULL,
|
|
16
|
+
created_at TEXT NOT NULL,
|
|
17
|
+
updated_at TEXT NOT NULL,
|
|
18
|
+
UNIQUE (installation_id, configuration_type, configuration_key)
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
CREATE INDEX configuration_drafts_type_idx
|
|
22
|
+
ON configuration_drafts(installation_id, configuration_type, configuration_key);
|
|
23
|
+
|
|
24
|
+
CREATE TABLE assistant_drafts (
|
|
25
|
+
id TEXT PRIMARY KEY,
|
|
26
|
+
installation_id TEXT NOT NULL REFERENCES installations(id) ON DELETE CASCADE,
|
|
27
|
+
session_id TEXT NOT NULL REFERENCES assistant_sessions(id) ON DELETE CASCADE,
|
|
28
|
+
principal_id TEXT NOT NULL,
|
|
29
|
+
draft_type TEXT NOT NULL CHECK (draft_type IN ('workflow', 'form', 'policy', 'template', 'routing_rules')),
|
|
30
|
+
target_id TEXT,
|
|
31
|
+
title TEXT NOT NULL,
|
|
32
|
+
content_json TEXT NOT NULL,
|
|
33
|
+
content_digest TEXT NOT NULL,
|
|
34
|
+
status TEXT NOT NULL DEFAULT 'draft' CHECK (status IN ('draft', 'adopted', 'expired')),
|
|
35
|
+
idempotency_key TEXT NOT NULL,
|
|
36
|
+
created_at TEXT NOT NULL,
|
|
37
|
+
adopted_at TEXT,
|
|
38
|
+
adopted_target_id TEXT,
|
|
39
|
+
UNIQUE (session_id, idempotency_key)
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
CREATE INDEX assistant_drafts_principal_idx
|
|
43
|
+
ON assistant_drafts(principal_id, status, created_at DESC, id DESC);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
ALTER TABLE installations ADD COLUMN settings_json TEXT NOT NULL DEFAULT '{}';
|
|
4
|
+
ALTER TABLE application_integrations ADD COLUMN scopes_json TEXT NOT NULL DEFAULT '["submit_reports","mint_context_tokens"]';
|
|
5
|
+
|
|
6
|
+
CREATE TABLE integration_api_keys (
|
|
7
|
+
id TEXT PRIMARY KEY,
|
|
8
|
+
integration_id TEXT NOT NULL REFERENCES application_integrations(id) ON DELETE CASCADE,
|
|
9
|
+
key_id TEXT NOT NULL UNIQUE,
|
|
10
|
+
key_hash TEXT NOT NULL UNIQUE,
|
|
11
|
+
status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'revoked', 'expired')),
|
|
12
|
+
valid_from TEXT NOT NULL,
|
|
13
|
+
expires_at TEXT,
|
|
14
|
+
created_by TEXT NOT NULL,
|
|
15
|
+
created_at TEXT NOT NULL,
|
|
16
|
+
revoked_by TEXT,
|
|
17
|
+
revoked_at TEXT
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
CREATE INDEX integration_api_keys_auth_idx
|
|
21
|
+
ON integration_api_keys(integration_id, status, valid_from, expires_at, id);
|
|
22
|
+
|
|
23
|
+
INSERT OR IGNORE INTO installation_features (
|
|
24
|
+
installation_id, feature_key, state, capability_json, checked_at, revision
|
|
25
|
+
) VALUES
|
|
26
|
+
('default', 'database', 'ready', '{}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 1),
|
|
27
|
+
('default', 'workflow_runtime', 'setup_required', '{}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 1),
|
|
28
|
+
('default', 'workers_ai', 'setup_required', '{}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 1),
|
|
29
|
+
('default', 'object_storage', 'setup_required', '{}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 1),
|
|
30
|
+
('default', 'queues', 'setup_required', '{}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 1),
|
|
31
|
+
('default', 'email', 'disabled', '{}', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 1);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
CREATE TABLE saved_views (
|
|
4
|
+
id TEXT PRIMARY KEY,
|
|
5
|
+
installation_id TEXT NOT NULL REFERENCES installations(id) ON DELETE CASCADE,
|
|
6
|
+
principal_id TEXT NOT NULL,
|
|
7
|
+
name TEXT NOT NULL,
|
|
8
|
+
filters_json TEXT NOT NULL,
|
|
9
|
+
created_at TEXT NOT NULL,
|
|
10
|
+
updated_at TEXT NOT NULL,
|
|
11
|
+
UNIQUE (installation_id, principal_id, name)
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
CREATE INDEX saved_views_principal_idx
|
|
15
|
+
ON saved_views(installation_id, principal_id, updated_at DESC, id DESC);
|
|
16
|
+
|
|
17
|
+
ALTER TABLE export_jobs ADD COLUMN idempotency_key TEXT;
|
|
18
|
+
|
|
19
|
+
CREATE UNIQUE INDEX export_jobs_idempotency_idx
|
|
20
|
+
ON export_jobs(installation_id, requested_by, idempotency_key)
|
|
21
|
+
WHERE idempotency_key IS NOT NULL;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
INSERT INTO routing_rule_versions (
|
|
4
|
+
id, installation_id, version, rules_json, fixture_results_json,
|
|
5
|
+
published_at, created_by, created_at
|
|
6
|
+
)
|
|
7
|
+
SELECT
|
|
8
|
+
'default-routing-v1', 'default', 1,
|
|
9
|
+
'{"default_queue_id":"standard-human","safeguard_queue_id":"urgent-human","intake_enrichment_component_ids":[],"rules":[],"fixtures":[]}',
|
|
10
|
+
'{"valid":true,"tested_at":"migration"}',
|
|
11
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
12
|
+
WHERE NOT EXISTS (
|
|
13
|
+
SELECT 1 FROM routing_rule_versions
|
|
14
|
+
WHERE installation_id = 'default' AND published_at IS NOT NULL
|
|
15
|
+
);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
-- Supply the first immutable Safest-owned specialist component.
|
|
2
|
+
|
|
3
|
+
INSERT OR IGNORE INTO component_definitions (
|
|
4
|
+
id, installation_id, component_key, name, description, component_kind,
|
|
5
|
+
effect_class, owner_kind, status, active_version_id, created_by,
|
|
6
|
+
created_at, updated_at
|
|
7
|
+
) VALUES (
|
|
8
|
+
'safest-builtin-phishing-url', 'default', 'safest-builtin-phishing-url',
|
|
9
|
+
'Phishing URL specialist',
|
|
10
|
+
'Deterministic, read-only URL normalization and phishing-risk signals. It never fetches the submitted URL and records unavailable reputation/content checks as uncertainty.',
|
|
11
|
+
'specialist_agent', 'read_only', 'safest', 'active', NULL, 'system',
|
|
12
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
INSERT OR IGNORE INTO component_versions (
|
|
16
|
+
id, definition_id, version, implementation_kind, implementation_reference,
|
|
17
|
+
input_schema_json, output_schema_json, allowed_input_fields_json,
|
|
18
|
+
data_classifications_json, connection_version_id, risk_class,
|
|
19
|
+
timeout_policy_json, retry_policy_json, cache_policy_json,
|
|
20
|
+
concurrency_policy_json, budget_policy_json, approval_policy_json,
|
|
21
|
+
tool_manifest_json, compatibility_json, package_digest,
|
|
22
|
+
signature_metadata_json, published_at, retired_at, created_by, created_at
|
|
23
|
+
)
|
|
24
|
+
SELECT
|
|
25
|
+
'safest-builtin-phishing-url-v1', 'safest-builtin-phishing-url', 1,
|
|
26
|
+
'specialist_agent', 'phishing-url-v1',
|
|
27
|
+
'{"type":"object","additionalProperties":false,"required":["url"],"properties":{"url":{"type":"string","minLength":1,"maxLength":2048}}}',
|
|
28
|
+
'{"type":"object","additionalProperties":false,"required":["normalized_url","normalized_url_hash","hostname_hash","scheme","signals","conclusion","summary","uncertainty","confidence"],"properties":{"normalized_url":{"type":"string"},"normalized_url_hash":{"type":"string"},"hostname_hash":{"type":"string"},"scheme":{"type":"string","enum":["http","https"]},"signals":{"type":"array","items":{"type":"string"}},"conclusion":{"type":"string","enum":["likely_phishing","suspicious","no_phishing_signal","unavailable","escalate"]},"summary":{"type":"string"},"uncertainty":{"type":"array","items":{"type":"string"}},"confidence":{"type":"number","minimum":0,"maximum":1}}}',
|
|
29
|
+
'["target.customer_url","answers.url"]',
|
|
30
|
+
'["report_operational","potentially_sensitive_url"]', NULL, 'low',
|
|
31
|
+
'{"timeout_ms":1500}', '{"maximum_attempts":1}',
|
|
32
|
+
'{"enabled":true,"ttl_seconds":3600,"key_fields":["url"]}',
|
|
33
|
+
'{"maximum_concurrency":20}', '{"metric":"calls","maximum_per_day":10000}',
|
|
34
|
+
'{}', '["url_parser","hostname_heuristics"]',
|
|
35
|
+
'{"fixture_evidence":{"passed":true,"validated_by":"safest_release","fixtures":["suspicious-login-url"]},"network_access":false,"runtime_protocol":"1"}',
|
|
36
|
+
'sha256:a2072d7111273ad5038ae0f2e11c3e3e227972a56b8ed71162a5f402d889829d',
|
|
37
|
+
'{"publisher":"safest","source":"built_in","digest_basis":"src/component-executor.ts"}',
|
|
38
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now'), NULL, 'system',
|
|
39
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
40
|
+
WHERE EXISTS (SELECT 1 FROM component_definitions WHERE id = 'safest-builtin-phishing-url');
|
|
41
|
+
|
|
42
|
+
UPDATE component_definitions
|
|
43
|
+
SET active_version_id = 'safest-builtin-phishing-url-v1',
|
|
44
|
+
updated_at = strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
45
|
+
WHERE id = 'safest-builtin-phishing-url'
|
|
46
|
+
AND EXISTS (SELECT 1 FROM component_versions WHERE id = 'safest-builtin-phishing-url-v1');
|
|
47
|
+
|
|
48
|
+
INSERT OR IGNORE INTO component_fixtures (
|
|
49
|
+
id, component_version_id, name, input_json, expected_json,
|
|
50
|
+
expected_status, created_by, created_at
|
|
51
|
+
)
|
|
52
|
+
SELECT
|
|
53
|
+
'safest-builtin-phishing-url-v1-fixture-suspicious',
|
|
54
|
+
'safest-builtin-phishing-url-v1', 'suspicious-login-url',
|
|
55
|
+
'{"url":"http://login.verify.example.com/account"}',
|
|
56
|
+
'{"normalized_url":"http://login.verify.example.com/account","normalized_url_hash":"sha256:f19ea3e9f98e298edbff77f8bd16194a45dc0b8677fc43ef1430904cd91a8355","hostname_hash":"sha256:852ead493ae4fd09da4de58d1f1ba7f9f96a464fc73662f110fb8a1044ebd249","scheme":"http","signals":["credential_lure_term","plaintext_transport"],"conclusion":"suspicious","summary":"Observed 2 deterministic phishing-risk signal(s).","uncertainty":["dns_reputation_and_content_not_checked"],"confidence":0.69}',
|
|
57
|
+
'succeeded', 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
58
|
+
WHERE EXISTS (SELECT 1 FROM component_versions WHERE id = 'safest-builtin-phishing-url-v1');
|
|
59
|
+
|
|
60
|
+
INSERT OR IGNORE INTO component_test_runs (
|
|
61
|
+
id, component_version_id, fixture_id, status, output_json,
|
|
62
|
+
error_code, started_by, started_at, finished_at
|
|
63
|
+
)
|
|
64
|
+
SELECT
|
|
65
|
+
'safest-builtin-phishing-url-v1-test-suspicious',
|
|
66
|
+
'safest-builtin-phishing-url-v1',
|
|
67
|
+
'safest-builtin-phishing-url-v1-fixture-suspicious', 'passed',
|
|
68
|
+
'{"mode":"simulated","validated_by":"safest_release","network_access":false}',
|
|
69
|
+
NULL, 'system', strftime('%Y-%m-%dT%H:%M:%fZ', 'now'),
|
|
70
|
+
strftime('%Y-%m-%dT%H:%M:%fZ', 'now')
|
|
71
|
+
WHERE EXISTS (SELECT 1 FROM component_fixtures WHERE id = 'safest-builtin-phishing-url-v1-fixture-suspicious');
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
-- Preserve webhook definitions created after the component registry was introduced.
|
|
4
|
+
INSERT OR IGNORE INTO connection_definitions (
|
|
5
|
+
id, installation_id, connection_key, name, description, kind, status,
|
|
6
|
+
active_version_id, created_by, created_at, updated_at
|
|
7
|
+
)
|
|
8
|
+
SELECT
|
|
9
|
+
'legacy-enrichment-connection:' || d.id,
|
|
10
|
+
d.installation_id,
|
|
11
|
+
'legacy-' || d.enrichment_key,
|
|
12
|
+
d.name || ' connection',
|
|
13
|
+
d.description,
|
|
14
|
+
'webhook',
|
|
15
|
+
CASE d.status WHEN 'paused' THEN 'paused' WHEN 'archived' THEN 'archived' ELSE 'active' END,
|
|
16
|
+
'legacy-enrichment-connection-version:' || d.active_version_id,
|
|
17
|
+
d.created_by,
|
|
18
|
+
d.created_at,
|
|
19
|
+
d.updated_at
|
|
20
|
+
FROM enrichment_definitions d;
|
|
21
|
+
|
|
22
|
+
INSERT OR IGNORE INTO connection_versions (
|
|
23
|
+
id, connection_id, version, base_url, service_binding_name,
|
|
24
|
+
allowed_hosts_json, allowed_methods_json, allowed_path_prefixes_json,
|
|
25
|
+
redirect_policy_json, request_limit_bytes, response_limit_bytes,
|
|
26
|
+
response_content_types_json, timeout_ms, concurrency_limit,
|
|
27
|
+
requests_per_window, window_seconds, credential_strategy, secret_reference,
|
|
28
|
+
signing_strategy_json, oauth_configuration_json, published_at, retired_at,
|
|
29
|
+
created_by, created_at
|
|
30
|
+
)
|
|
31
|
+
SELECT
|
|
32
|
+
'legacy-enrichment-connection-version:' || v.id,
|
|
33
|
+
'legacy-enrichment-connection:' || v.definition_id,
|
|
34
|
+
v.version,
|
|
35
|
+
v.webhook_url,
|
|
36
|
+
NULL,
|
|
37
|
+
'[]',
|
|
38
|
+
'["POST"]',
|
|
39
|
+
'["/"]',
|
|
40
|
+
'{"follow":false,"maximum":0}',
|
|
41
|
+
65536,
|
|
42
|
+
262144,
|
|
43
|
+
'["application/json"]',
|
|
44
|
+
v.timeout_ms,
|
|
45
|
+
8,
|
|
46
|
+
60,
|
|
47
|
+
60,
|
|
48
|
+
'hmac',
|
|
49
|
+
v.secret_binding,
|
|
50
|
+
'{"kind":"safest_hmac_v1"}',
|
|
51
|
+
'{}',
|
|
52
|
+
v.published_at,
|
|
53
|
+
NULL,
|
|
54
|
+
v.created_by,
|
|
55
|
+
v.created_at
|
|
56
|
+
FROM enrichment_definition_versions v;
|
|
57
|
+
|
|
58
|
+
UPDATE connection_versions
|
|
59
|
+
SET allowed_hosts_json = json_array(
|
|
60
|
+
substr(
|
|
61
|
+
base_url,
|
|
62
|
+
instr(base_url, '://') + 3,
|
|
63
|
+
CASE
|
|
64
|
+
WHEN instr(substr(base_url, instr(base_url, '://') + 3), '/') = 0
|
|
65
|
+
THEN length(base_url)
|
|
66
|
+
ELSE instr(substr(base_url, instr(base_url, '://') + 3), '/') - 1
|
|
67
|
+
END
|
|
68
|
+
)
|
|
69
|
+
)
|
|
70
|
+
WHERE id LIKE 'legacy-enrichment-connection-version:%';
|
|
71
|
+
|
|
72
|
+
INSERT OR IGNORE INTO connection_health (
|
|
73
|
+
connection_version_id, state, consecutive_failures, revision, updated_at
|
|
74
|
+
)
|
|
75
|
+
SELECT
|
|
76
|
+
'legacy-enrichment-connection-version:' || v.id,
|
|
77
|
+
'unknown',
|
|
78
|
+
0,
|
|
79
|
+
1,
|
|
80
|
+
v.created_at
|
|
81
|
+
FROM enrichment_definition_versions v;
|
|
82
|
+
|
|
83
|
+
INSERT OR IGNORE INTO component_definitions (
|
|
84
|
+
id, installation_id, component_key, name, description, component_kind,
|
|
85
|
+
effect_class, owner_kind, status, active_version_id, created_by, created_at, updated_at
|
|
86
|
+
)
|
|
87
|
+
SELECT
|
|
88
|
+
d.id,
|
|
89
|
+
d.installation_id,
|
|
90
|
+
d.enrichment_key,
|
|
91
|
+
d.name,
|
|
92
|
+
d.description,
|
|
93
|
+
'webhook_enrichment',
|
|
94
|
+
'read_only',
|
|
95
|
+
'customer',
|
|
96
|
+
CASE d.status WHEN 'paused' THEN 'paused' WHEN 'archived' THEN 'archived' ELSE 'active' END,
|
|
97
|
+
d.active_version_id,
|
|
98
|
+
d.created_by,
|
|
99
|
+
d.created_at,
|
|
100
|
+
d.updated_at
|
|
101
|
+
FROM enrichment_definitions d;
|
|
102
|
+
|
|
103
|
+
INSERT OR IGNORE INTO component_versions (
|
|
104
|
+
id, definition_id, version, implementation_kind, implementation_reference,
|
|
105
|
+
input_schema_json, output_schema_json, allowed_input_fields_json,
|
|
106
|
+
data_classifications_json, connection_version_id, risk_class,
|
|
107
|
+
timeout_policy_json, retry_policy_json, cache_policy_json,
|
|
108
|
+
concurrency_policy_json, budget_policy_json, approval_policy_json,
|
|
109
|
+
tool_manifest_json, compatibility_json, published_at, created_by, created_at
|
|
110
|
+
)
|
|
111
|
+
SELECT
|
|
112
|
+
v.id,
|
|
113
|
+
v.definition_id,
|
|
114
|
+
v.version,
|
|
115
|
+
'webhook',
|
|
116
|
+
v.webhook_url,
|
|
117
|
+
json_object('type', 'object', 'properties', json(v.input_fields_json)),
|
|
118
|
+
v.output_schema_json,
|
|
119
|
+
v.input_fields_json,
|
|
120
|
+
'["report_operational"]',
|
|
121
|
+
'legacy-enrichment-connection-version:' || v.id,
|
|
122
|
+
'low',
|
|
123
|
+
json_object('timeout_ms', v.timeout_ms),
|
|
124
|
+
json_object('maximum_attempts', v.max_attempts, 'backoff', 'exponential'),
|
|
125
|
+
json_object('enabled', CASE WHEN v.ttl_seconds > 0 THEN json('true') ELSE json('false') END, 'ttl_seconds', v.ttl_seconds),
|
|
126
|
+
'{"maximum_concurrency":8}',
|
|
127
|
+
'{}',
|
|
128
|
+
'{}',
|
|
129
|
+
'[]',
|
|
130
|
+
'{}',
|
|
131
|
+
v.published_at,
|
|
132
|
+
v.created_by,
|
|
133
|
+
v.created_at
|
|
134
|
+
FROM enrichment_definition_versions v;
|
|
135
|
+
|
|
136
|
+
UPDATE component_versions
|
|
137
|
+
SET compatibility_json = json_remove(compatibility_json, '$.legacy_enrichment')
|
|
138
|
+
WHERE json_type(compatibility_json, '$.legacy_enrichment') IS NOT NULL;
|
|
139
|
+
|
|
140
|
+
-- Convert the pre-mapping routing field, then make the explicit mapping shape canonical.
|
|
141
|
+
UPDATE routing_rule_versions
|
|
142
|
+
SET rules_json = json_set(
|
|
143
|
+
rules_json,
|
|
144
|
+
'$.intake_enrichments',
|
|
145
|
+
COALESCE(
|
|
146
|
+
(
|
|
147
|
+
SELECT json_group_array(json_object(
|
|
148
|
+
'component_version_id', value,
|
|
149
|
+
'input_mapping', json('{}')
|
|
150
|
+
))
|
|
151
|
+
FROM json_each(routing_rule_versions.rules_json, '$.intake_enrichment_component_ids')
|
|
152
|
+
WHERE type = 'text'
|
|
153
|
+
),
|
|
154
|
+
json('[]')
|
|
155
|
+
)
|
|
156
|
+
)
|
|
157
|
+
WHERE json_type(rules_json, '$.intake_enrichment_component_ids') = 'array'
|
|
158
|
+
AND json_type(rules_json, '$.intake_enrichments') IS NULL;
|
|
159
|
+
|
|
160
|
+
UPDATE routing_rule_versions
|
|
161
|
+
SET rules_json = json_remove(rules_json, '$.intake_enrichment_component_ids')
|
|
162
|
+
WHERE json_type(rules_json, '$.intake_enrichment_component_ids') IS NOT NULL;
|
|
163
|
+
|
|
164
|
+
UPDATE queue_versions
|
|
165
|
+
SET routing_criteria_json = '{"match":"all","conditions":[]}',
|
|
166
|
+
enrichment_requirements_json = '[]';
|
|
167
|
+
|
|
168
|
+
DROP TABLE enrichment_results;
|
|
169
|
+
DROP TABLE enrichment_attempts;
|
|
170
|
+
DROP TABLE enrichment_requests;
|
|
171
|
+
DROP TABLE enrichment_definition_versions;
|
|
172
|
+
DROP TABLE enrichment_definitions;
|
|
173
|
+
|
|
174
|
+
-- Retain direct human-decision and appeal action delivery as a distinct, accurately named outbox.
|
|
175
|
+
DROP INDEX action_outbox_due_idx;
|
|
176
|
+
DROP INDEX action_outbox_reconcile_idx;
|
|
177
|
+
ALTER TABLE action_outbox RENAME TO decision_action_outbox;
|
|
178
|
+
ALTER TABLE action_attempts RENAME TO decision_action_attempts;
|
|
179
|
+
CREATE INDEX decision_action_outbox_due_idx
|
|
180
|
+
ON decision_action_outbox(status, next_attempt_at, id);
|
|
181
|
+
CREATE INDEX decision_action_outbox_reconcile_idx
|
|
182
|
+
ON decision_action_outbox(terminal, status, next_attempt_at, lease_expires_at, id);
|
|
183
|
+
|
|
184
|
+
ALTER TABLE dead_letter_items RENAME TO dead_letter_items_v6;
|
|
185
|
+
|
|
186
|
+
CREATE TABLE dead_letter_items (
|
|
187
|
+
id TEXT PRIMARY KEY,
|
|
188
|
+
fingerprint TEXT NOT NULL UNIQUE,
|
|
189
|
+
source_queue TEXT NOT NULL,
|
|
190
|
+
source_message_id TEXT NOT NULL,
|
|
191
|
+
job_type TEXT NOT NULL CHECK (job_type IN (
|
|
192
|
+
'route_report', 'process_ai_report', 'fetch_evidence',
|
|
193
|
+
'dispatch_workflow', 'deliver_action', 'deliver_notification', 'deliver_email',
|
|
194
|
+
'apply_action_proposal', 'invalid'
|
|
195
|
+
)),
|
|
196
|
+
job_id TEXT,
|
|
197
|
+
report_id TEXT REFERENCES reports(id),
|
|
198
|
+
outbox_id TEXT,
|
|
199
|
+
incident_id TEXT REFERENCES operations_incidents(id) ON DELETE SET NULL,
|
|
200
|
+
state TEXT NOT NULL DEFAULT 'open' CHECK (state IN ('open', 'acknowledged', 'resolved')),
|
|
201
|
+
error_code TEXT NOT NULL,
|
|
202
|
+
occurrence_count INTEGER NOT NULL DEFAULT 1 CHECK (occurrence_count > 0),
|
|
203
|
+
details_json TEXT NOT NULL DEFAULT '{}',
|
|
204
|
+
first_seen_at TEXT NOT NULL,
|
|
205
|
+
last_seen_at TEXT NOT NULL,
|
|
206
|
+
resolved_at TEXT
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
INSERT INTO dead_letter_items (
|
|
210
|
+
id, fingerprint, source_queue, source_message_id, job_type, job_id,
|
|
211
|
+
report_id, outbox_id, incident_id, state, error_code, occurrence_count,
|
|
212
|
+
details_json, first_seen_at, last_seen_at, resolved_at
|
|
213
|
+
)
|
|
214
|
+
SELECT
|
|
215
|
+
id, fingerprint, source_queue, source_message_id,
|
|
216
|
+
CASE job_type WHEN 'run_enrichment' THEN 'invalid' ELSE job_type END,
|
|
217
|
+
job_id, report_id, outbox_id, incident_id, state, error_code, occurrence_count,
|
|
218
|
+
details_json, first_seen_at, last_seen_at, resolved_at
|
|
219
|
+
FROM dead_letter_items_v6;
|
|
220
|
+
|
|
221
|
+
DROP TABLE dead_letter_items_v6;
|
|
222
|
+
|
|
223
|
+
CREATE INDEX dead_letter_items_state_idx
|
|
224
|
+
ON dead_letter_items(state, last_seen_at DESC, id DESC);
|
|
225
|
+
CREATE INDEX dead_letter_items_report_idx
|
|
226
|
+
ON dead_letter_items(report_id, last_seen_at DESC, id DESC);
|
|
227
|
+
CREATE INDEX dead_letter_items_incident_idx
|
|
228
|
+
ON dead_letter_items(incident_id, state, last_seen_at DESC, id DESC);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
ALTER TABLE application_integrations
|
|
4
|
+
ADD COLUMN channel_mode TEXT NOT NULL DEFAULT 'contextual'
|
|
5
|
+
CHECK (channel_mode IN ('contextual', 'anonymous'));
|
|
6
|
+
|
|
7
|
+
ALTER TABLE application_integrations
|
|
8
|
+
ADD COLUMN form_version_id TEXT REFERENCES report_form_versions(id);
|
|
9
|
+
|
|
10
|
+
ALTER TABLE application_integrations
|
|
11
|
+
ADD COLUMN context_schema_json TEXT NOT NULL
|
|
12
|
+
DEFAULT '{"version":1,"allow_unknown":true,"fields":[]}';
|
|
13
|
+
|
|
14
|
+
ALTER TABLE report_targets
|
|
15
|
+
ADD COLUMN routing_facts_json TEXT NOT NULL DEFAULT '{}';
|
|
16
|
+
|
|
17
|
+
UPDATE report_targets SET routing_facts_json = signed_facts_json;
|
|
18
|
+
|
|
19
|
+
CREATE TABLE report_contexts (
|
|
20
|
+
id TEXT PRIMARY KEY,
|
|
21
|
+
installation_id TEXT NOT NULL REFERENCES installations(id) ON DELETE CASCADE,
|
|
22
|
+
integration_id TEXT NOT NULL REFERENCES application_integrations(id) ON DELETE CASCADE,
|
|
23
|
+
form_version_id TEXT NOT NULL REFERENCES report_form_versions(id),
|
|
24
|
+
origin TEXT NOT NULL,
|
|
25
|
+
reporter_reference TEXT,
|
|
26
|
+
target_type TEXT NOT NULL,
|
|
27
|
+
target_reference TEXT NOT NULL,
|
|
28
|
+
target_owner_reference TEXT,
|
|
29
|
+
target_customer_url TEXT,
|
|
30
|
+
trusted_facts_json TEXT NOT NULL DEFAULT '{}',
|
|
31
|
+
routing_facts_json TEXT NOT NULL DEFAULT '{}',
|
|
32
|
+
context_schema_version INTEGER NOT NULL DEFAULT 1 CHECK (context_schema_version > 0),
|
|
33
|
+
assertion_source TEXT NOT NULL DEFAULT 'customer_backend'
|
|
34
|
+
CHECK (assertion_source IN ('customer_backend', 'resolve_hosted')),
|
|
35
|
+
created_at TEXT NOT NULL,
|
|
36
|
+
expires_at TEXT NOT NULL,
|
|
37
|
+
used_at TEXT,
|
|
38
|
+
report_id TEXT REFERENCES reports(id) ON DELETE SET NULL
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
CREATE INDEX report_contexts_expiry_idx
|
|
42
|
+
ON report_contexts(expires_at, used_at, id);
|
|
43
|
+
|
|
44
|
+
CREATE INDEX report_contexts_integration_idx
|
|
45
|
+
ON report_contexts(integration_id, created_at DESC, id);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
-- Status portals and bearer capabilities are intentionally retired.
|
|
2
|
+
-- Reporter communication now leaves Resolve only through signed webhooks or email delivery.
|
|
3
|
+
DROP TABLE portal_sessions;
|
|
4
|
+
|
|
5
|
+
UPDATE report_participants
|
|
6
|
+
SET contact_mode = CASE
|
|
7
|
+
WHEN reference IS NOT NULL OR contact_ciphertext IS NOT NULL THEN 'customer_notification'
|
|
8
|
+
ELSE 'none'
|
|
9
|
+
END
|
|
10
|
+
WHERE contact_mode = 'portal';
|
|
11
|
+
|
|
12
|
+
CREATE TRIGGER report_participants_reject_portal_insert
|
|
13
|
+
BEFORE INSERT ON report_participants
|
|
14
|
+
WHEN NEW.contact_mode = 'portal'
|
|
15
|
+
BEGIN
|
|
16
|
+
SELECT RAISE(ABORT, 'portal contact mode has been removed');
|
|
17
|
+
END;
|
|
18
|
+
|
|
19
|
+
CREATE TRIGGER report_participants_reject_portal_update
|
|
20
|
+
BEFORE UPDATE OF contact_mode ON report_participants
|
|
21
|
+
WHEN NEW.contact_mode = 'portal'
|
|
22
|
+
BEGIN
|
|
23
|
+
SELECT RAISE(ABORT, 'portal contact mode has been removed');
|
|
24
|
+
END;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
PRAGMA foreign_keys = ON;
|
|
2
|
+
|
|
3
|
+
DROP TABLE operator_password_reset_limits;
|
|
4
|
+
DROP TABLE operator_password_resets;
|
|
5
|
+
DROP TABLE operator_login_limits;
|
|
6
|
+
|
|
7
|
+
ALTER TABLE operator_sessions RENAME TO infrastructure_owner_sessions;
|
|
8
|
+
DROP INDEX operator_sessions_user_idx;
|
|
9
|
+
DROP INDEX operator_sessions_expiry_idx;
|
|
10
|
+
CREATE INDEX infrastructure_owner_sessions_user_idx
|
|
11
|
+
ON infrastructure_owner_sessions(user_id, revoked_at, expires_at DESC, id);
|
|
12
|
+
CREATE INDEX infrastructure_owner_sessions_expiry_idx
|
|
13
|
+
ON infrastructure_owner_sessions(revoked_at, expires_at, id);
|
|
14
|
+
|
|
15
|
+
ALTER TABLE operator_users DROP COLUMN password_hash;
|
|
16
|
+
ALTER TABLE operator_users DROP COLUMN password_salt;
|
|
17
|
+
ALTER TABLE operator_users DROP COLUMN password_iterations;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "safest-resolve-installation",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"safestToolsVersion": "0.2.0-resolve",
|
|
5
|
+
"private": true,
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "npm run build:console",
|
|
10
|
+
"build:console": "vite build --config vite.console.config.ts",
|
|
11
|
+
"secrets:init": "node scripts/reports-secrets.mjs",
|
|
12
|
+
"setup": "npm run build:console && node scripts/reports-deploy.mjs",
|
|
13
|
+
"setup:plan": "node scripts/reports-deploy.mjs --plan",
|
|
14
|
+
"upgrade": "npm run backup && npm run build:console && node scripts/reports-deploy.mjs --upgrade",
|
|
15
|
+
"upgrade:plan": "node scripts/reports-deploy.mjs --upgrade --plan",
|
|
16
|
+
"backup": "node scripts/reports-backup.mjs",
|
|
17
|
+
"backup:plan": "node scripts/reports-backup.mjs --plan",
|
|
18
|
+
"restore:verify": "node scripts/reports-restore.mjs --verify",
|
|
19
|
+
"restore:plan": "node scripts/reports-restore.mjs --plan",
|
|
20
|
+
"uninstall:plan": "node scripts/reports-uninstall-plan.mjs",
|
|
21
|
+
"check:browser": "node --check public/console/auth-shell.js && node --check public/widget.js && node --check public/embed/embed.js && node --check public/public-report.js",
|
|
22
|
+
"check:console": "tsc --project tsconfig.console.json --noEmit",
|
|
23
|
+
"check": "npm run check:browser && npm run check:console && tsc --noEmit",
|
|
24
|
+
"console:dev": "vite build --config vite.console.config.ts --watch",
|
|
25
|
+
"deploy:dry-run": "npm run build:console && wrangler deploy --dry-run --outdir dist/reports-worker"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@clack/prompts": "^1.7.0",
|
|
29
|
+
"@cloudflare/dynamic-workflows": "^0.1.1",
|
|
30
|
+
"better-auth": "^1.7.2",
|
|
31
|
+
"jose": "^6.2.10",
|
|
32
|
+
"react": "^19.2.8",
|
|
33
|
+
"react-dom": "^19.2.8"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@cloudflare/workers-types": "^5.20260828.1",
|
|
37
|
+
"@types/react": "^19.2.18",
|
|
38
|
+
"@types/react-dom": "^19.2.5",
|
|
39
|
+
"@vitejs/plugin-react": "^6.1.1",
|
|
40
|
+
"typescript": "^7.0.2",
|
|
41
|
+
"vite": "^8.2.2",
|
|
42
|
+
"wrangler": "^4.127.0"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=20.12.0"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Content-Security-Policy: default-src 'self'; script-src 'self' https://challenges.cloudflare.com; style-src 'self' 'unsafe-inline' https:; font-src 'self' data: https:; img-src 'self' data: https:; connect-src 'self' https://challenges.cloudflare.com; frame-src https://challenges.cloudflare.com; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'
|
|
3
|
+
Referrer-Policy: no-referrer
|
|
4
|
+
X-Content-Type-Options: nosniff
|
|
5
|
+
X-Frame-Options: DENY
|
|
6
|
+
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
|
|
7
|
+
|
|
8
|
+
/
|
|
9
|
+
Cache-Control: public, max-age=0, must-revalidate
|
|
10
|
+
|
|
11
|
+
/widget.js
|
|
12
|
+
Cache-Control: public, max-age=0, must-revalidate
|
|
13
|
+
|
|
14
|
+
/widget.css
|
|
15
|
+
Cache-Control: public, max-age=0, must-revalidate
|
|
16
|
+
|
|
17
|
+
/embed/*
|
|
18
|
+
Cache-Control: no-store
|
|
19
|
+
|
|
20
|
+
/customer-brand.js
|
|
21
|
+
Cache-Control: public, max-age=0, must-revalidate
|
|
22
|
+
|
|
23
|
+
/styles.css
|
|
24
|
+
Cache-Control: public, max-age=0, must-revalidate
|
|
25
|
+
|
|
26
|
+
/report/*
|
|
27
|
+
Cache-Control: no-store
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">Safest app icon</title>
|
|
3
|
+
<desc id="desc">The Safest open-boundary mark on a deep evergreen tile.</desc>
|
|
4
|
+
<rect x="2" y="2" width="60" height="60" rx="17" fill="#0B2B20"/>
|
|
5
|
+
<path d="M 35.000 14.000 H 29.000 C 20.716 14.000 14.000 20.716 14.000 29.000 V 32.000" fill="none" stroke="#FFFFFF" stroke-width="11.500" stroke-linecap="round" stroke-linejoin="round"/>
|
|
6
|
+
<path d="M 29.000 50.000 H 35.000 C 43.284 50.000 50.000 43.284 50.000 35.000 V 32.000" fill="none" stroke="#CBEF68" stroke-width="11.500" stroke-linecap="round" stroke-linejoin="round"/>
|
|
7
|
+
</svg>
|