-
Notifications
You must be signed in to change notification settings - Fork 7
Docs/add security policy #89
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # Security Policy | ||
|
|
||
| ## Supported Versions | ||
|
|
||
| The table below details which versions of FlowCraft are currently supported with security updates: | ||
|
|
||
| | Version | Supported | | ||
| | ------- | ------------------ | | ||
| | 1.x.x | :white_check_mark: | | ||
| | < 1.0.0 | :x: | | ||
|
|
||
| ## Reporting a Vulnerability | ||
|
|
||
| The FlowCraft team takes security and user privacy seriously. If you discover a security vulnerability or potential exploit, we appreciate your help in disclosing it to us responsibly. | ||
|
|
||
| ### Responsible Disclosure Guidelines | ||
|
|
||
| **Please do NOT create a public GitHub issue, pull request, or discussion for security vulnerabilities.** | ||
|
|
||
| Instead, report vulnerabilities privately through one of the following channels: | ||
|
|
||
| 1. **GitHub Private Vulnerability Reporting:** Use the "Report a vulnerability" button under the **Security** tab of the repository. | ||
| 2. **Email Contact:** Send a private email to the project maintainers at `security@flowcraft.dev`. | ||
|
|
||
| ### What to Include in Your Report | ||
|
|
||
| To help us evaluate and address the issue quickly, please provide: | ||
|
|
||
| - A clear summary of the vulnerability and its potential impact. | ||
| - Detailed step-by-step instructions, screenshots, or a minimal Proof-of-Concept (PoC) script to reproduce the issue. | ||
| - The browser environment, OS, and version of FlowCraft where the vulnerability was observed. | ||
| - Any proposed remediation or code fix recommendations (if available). | ||
|
|
||
| ### Response Timeline | ||
|
|
||
| - **Acknowledgment:** We aim to acknowledge receipt of your vulnerability report within **48 hours**. | ||
| - **Triage & Fix:** We will keep you informed as we investigate the vulnerability, work on a patch, and verify the resolution. | ||
| - **Public Disclosure:** Once a fix is released, we will coordinate public disclosure and credit security researchers who report issues in good faith. | ||
|
|
||
| Thank you for contributing to the security and safety of the open-source community! |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,7 @@ import CenterCanvas from './components/CenterCanvas'; | |
| import RightSidebar from './components/RightSidebar'; | ||
| import Toast from './components/Toast'; | ||
| import { Block, ToastConfig, LayoutDirection } from './types'; | ||
| import { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts'; | ||
|
|
||
| // Default blueprint layout tracking | ||
| const initialDemoBlocks: Block[] = [ | ||
|
|
@@ -88,6 +89,7 @@ export default function App() { | |
| const [layoutDirection, setLayoutDirection] = useState<LayoutDirection>('vertical'); | ||
| const [currentWorkspace, setCurrentWorkspace] = useState<string>('Form-Flow Sandbox'); | ||
| const [workspaces, setWorkspaces] = useState<string[]>(['Form-Flow Sandbox']); | ||
| const [showShortcutsHelp, setShowShortcutsHelp] = useState(false); | ||
|
|
||
| useEffect(() => { | ||
| try { | ||
|
|
@@ -251,6 +253,37 @@ export default function App() { | |
| showToast(`Block "${block.label}" removed`, 'info'); | ||
| }; | ||
|
|
||
| // Duplicate block (Ctrl+D / Cmd+D) | ||
| const handleDuplicateBlock = (id: string) => { | ||
| const original = blocks.find((b) => b.id === id); | ||
| if (!original) return; | ||
|
|
||
| const newId = `block-${Math.random().toString(36).substring(2, 9)}`; | ||
| const duplicatedBlock: Block = { | ||
| ...original, | ||
| id: newId, | ||
| label: `${original.label} (Copy)`, | ||
| }; | ||
|
|
||
| setBlocks((prev) => { | ||
| const idx = prev.findIndex((b) => b.id === id); | ||
| if (idx === -1) return [...prev, duplicatedBlock]; | ||
|
|
||
| const updated = [...prev]; | ||
| if (original.type !== 'decision') { | ||
| duplicatedBlock.targetId = original.targetId; | ||
| updated[idx] = { ...original, targetId: newId }; | ||
| } | ||
|
|
||
| updated.splice(idx + 1, 0, duplicatedBlock); | ||
| return updated; | ||
| }); | ||
|
|
||
| setSelectedBlockId(newId); | ||
| setActiveParentId(newId); | ||
| showToast(`Duplicated "${original.label}"`, 'success'); | ||
| }; | ||
|
|
||
| // Select and chain next process block | ||
| const handleSelectAndContinue = (parentBlock: Block) => { | ||
| setActiveParentId(parentBlock.id); | ||
|
|
@@ -284,6 +317,17 @@ export default function App() { | |
| } | ||
| }; | ||
|
|
||
| useKeyboardShortcuts({ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Keyboard navigation is broken once this global listener is mounted: Tab from toolbar, sidebar, or modal buttons is intercepted to cycle blocks instead of moving focus, and Delete/Backspace can remove the selected block while the help dialog is open. Scoping shortcuts to the canvas or excluding all interactive/modal targets before handling these keys would preserve native control behavior and prevent destructive actions behind the dialog. Prompt for AI agents |
||
| blocks, | ||
| selectedBlockId, | ||
| currentWorkspace, | ||
| onSelectBlock: setSelectedBlockId, | ||
| onDeleteBlock: handleDeleteBlock, | ||
| onDuplicateBlock: handleDuplicateBlock, | ||
| onSaveWorkspace: handleSaveWorkspace, | ||
| onToggleShortcutsHelp: () => setShowShortcutsHelp((prev) => !prev), | ||
| }); | ||
|
|
||
| const handleLoadWorkspace = (name: string) => { | ||
| try { | ||
| const data = localStorage.getItem('flowforge_workspaces'); | ||
|
|
@@ -475,6 +519,8 @@ export default function App() { | |
| toggleDarkMode={toggleDarkMode} | ||
| layoutDirection={layoutDirection} | ||
| onLayoutDirectionChange={setLayoutDirection} | ||
| showShortcutsHelp={showShortcutsHelp} | ||
| onToggleShortcutsHelp={() => setShowShortcutsHelp((prev) => !prev)} | ||
| /> | ||
|
|
||
| {/* RIGHT SIDEBAR PROPERTIES */} | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Duplicating a decision with populated branches creates a second unconnected source: the copy keeps the original yes/no targets, but this branch never rewires an incoming edge to the new ID. A decision-specific insertion strategy, or disabling duplication when its connection cannot be preserved, would avoid adding an unexpected orphaned flow node.
Prompt for AI agents