mirror of
https://github.com/supabase/supabase.git
synced 2026-10-08 02:45:07 +03:00
Prevent non owners from editing shared snippets (#30692)
* Prevent non owners from editing shared snippets * Add guard against saving snippet which is shared + has folder id * FIX
This commit is contained in:
1 parent
3e7a0df1f8
commit
f2d9203ea2
2 files changed
+98
-69
No files matched your search
@@ -8,13 +8,14 @@ import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage'
|
||||
import { useSelectedProject } from 'hooks/misc/useSelectedProject'
|
||||
import { LOCAL_STORAGE_KEYS } from 'lib/constants'
|
||||
import { useProfile } from 'lib/profile'
|
||||
import { useAppStateSnapshot } from 'state/app-state'
|
||||
import { useSqlEditorV2StateSnapshot } from 'state/sql-editor-v2'
|
||||
import { cn } from 'ui'
|
||||
import { Admonition } from 'ui-patterns'
|
||||
import { useIsAssistantV2Enabled } from '../App/FeaturePreview/FeaturePreviewContext'
|
||||
import { untitledSnippetTitle } from './SQLEditor.constants'
|
||||
import type { IStandaloneCodeEditor } from './SQLEditor.types'
|
||||
import { createSqlSnippetSkeletonV2 } from './SQLEditor.utils'
|
||||
import { useIsAssistantV2Enabled } from '../App/FeaturePreview/FeaturePreviewContext'
|
||||
import { useAppStateSnapshot } from 'state/app-state'
|
||||
|
||||
export type MonacoEditorProps = {
|
||||
id: string
|
||||
@@ -50,6 +51,8 @@ const MonacoEditor = ({
|
||||
)
|
||||
|
||||
const snippet = snapV2.snippets[id]
|
||||
const disableEdit =
|
||||
snippet?.snippet.visibility === 'project' && snippet?.snippet.owner_id !== profile?.id
|
||||
|
||||
const executeQueryRef = useRef(executeQuery)
|
||||
executeQueryRef.current = executeQuery
|
||||
@@ -152,57 +155,68 @@ const MonacoEditor = ({
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Editor
|
||||
className={cn(className, 'monaco-editor')}
|
||||
theme={'supabase'}
|
||||
onMount={handleEditorOnMount}
|
||||
onChange={handleEditorChange}
|
||||
defaultLanguage="pgsql"
|
||||
defaultValue={snippet?.snippet.content.sql}
|
||||
path={id}
|
||||
options={{
|
||||
tabSize: 2,
|
||||
fontSize: 13,
|
||||
minimap: { enabled: false },
|
||||
wordWrap: 'on',
|
||||
// [Joshen] Commenting the following out as it causes the autocomplete suggestion popover
|
||||
// to be positioned wrongly somehow. I'm not sure if this affects anything though, but leaving
|
||||
// comment just in case anyone might be wondering. Relevant issues:
|
||||
// - https://github.com/microsoft/monaco-editor/issues/2229
|
||||
// - https://github.com/microsoft/monaco-editor/issues/2503
|
||||
// fixedOverflowWidgets: true,
|
||||
suggest: {
|
||||
showMethods: intellisenseEnabled,
|
||||
showFunctions: intellisenseEnabled,
|
||||
showConstructors: intellisenseEnabled,
|
||||
showDeprecated: intellisenseEnabled,
|
||||
showFields: intellisenseEnabled,
|
||||
showVariables: intellisenseEnabled,
|
||||
showClasses: intellisenseEnabled,
|
||||
showStructs: intellisenseEnabled,
|
||||
showInterfaces: intellisenseEnabled,
|
||||
showModules: intellisenseEnabled,
|
||||
showProperties: intellisenseEnabled,
|
||||
showEvents: intellisenseEnabled,
|
||||
showOperators: intellisenseEnabled,
|
||||
showUnits: intellisenseEnabled,
|
||||
showValues: intellisenseEnabled,
|
||||
showConstants: intellisenseEnabled,
|
||||
showEnums: intellisenseEnabled,
|
||||
showEnumMembers: intellisenseEnabled,
|
||||
showKeywords: intellisenseEnabled,
|
||||
showWords: intellisenseEnabled,
|
||||
showColors: intellisenseEnabled,
|
||||
showFiles: intellisenseEnabled,
|
||||
showReferences: intellisenseEnabled,
|
||||
showFolders: intellisenseEnabled,
|
||||
showTypeParameters: intellisenseEnabled,
|
||||
showIssues: intellisenseEnabled,
|
||||
showUsers: intellisenseEnabled,
|
||||
showSnippets: intellisenseEnabled,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<>
|
||||
{disableEdit && (
|
||||
<Admonition
|
||||
type="default"
|
||||
className="m-0 py-2 rounded-none border-0 border-b [&>h5]:mb-0.5"
|
||||
title="This snippet has been shared to the project and is only editable by the owner who created this snippet"
|
||||
description='You may duplicate this snippet into a personal copy by right clicking on the snippet and selecting "Duplicate personal copy"'
|
||||
/>
|
||||
)}
|
||||
<Editor
|
||||
className={cn(className, 'monaco-editor')}
|
||||
theme={'supabase'}
|
||||
onMount={handleEditorOnMount}
|
||||
onChange={handleEditorChange}
|
||||
defaultLanguage="pgsql"
|
||||
defaultValue={snippet?.snippet.content.sql}
|
||||
path={id}
|
||||
options={{
|
||||
tabSize: 2,
|
||||
fontSize: 13,
|
||||
readOnly: disableEdit,
|
||||
minimap: { enabled: false },
|
||||
wordWrap: 'on',
|
||||
// [Joshen] Commenting the following out as it causes the autocomplete suggestion popover
|
||||
// to be positioned wrongly somehow. I'm not sure if this affects anything though, but leaving
|
||||
// comment just in case anyone might be wondering. Relevant issues:
|
||||
// - https://github.com/microsoft/monaco-editor/issues/2229
|
||||
// - https://github.com/microsoft/monaco-editor/issues/2503
|
||||
// fixedOverflowWidgets: true,
|
||||
suggest: {
|
||||
showMethods: intellisenseEnabled,
|
||||
showFunctions: intellisenseEnabled,
|
||||
showConstructors: intellisenseEnabled,
|
||||
showDeprecated: intellisenseEnabled,
|
||||
showFields: intellisenseEnabled,
|
||||
showVariables: intellisenseEnabled,
|
||||
showClasses: intellisenseEnabled,
|
||||
showStructs: intellisenseEnabled,
|
||||
showInterfaces: intellisenseEnabled,
|
||||
showModules: intellisenseEnabled,
|
||||
showProperties: intellisenseEnabled,
|
||||
showEvents: intellisenseEnabled,
|
||||
showOperators: intellisenseEnabled,
|
||||
showUnits: intellisenseEnabled,
|
||||
showValues: intellisenseEnabled,
|
||||
showConstants: intellisenseEnabled,
|
||||
showEnums: intellisenseEnabled,
|
||||
showEnumMembers: intellisenseEnabled,
|
||||
showKeywords: intellisenseEnabled,
|
||||
showWords: intellisenseEnabled,
|
||||
showColors: intellisenseEnabled,
|
||||
showFiles: intellisenseEnabled,
|
||||
showReferences: intellisenseEnabled,
|
||||
showFolders: intellisenseEnabled,
|
||||
showTypeParameters: intellisenseEnabled,
|
||||
showIssues: intellisenseEnabled,
|
||||
showUsers: intellisenseEnabled,
|
||||
showSnippets: intellisenseEnabled,
|
||||
},
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -462,22 +462,37 @@ if (typeof window !== 'undefined') {
|
||||
const folder = state.folders[id]
|
||||
|
||||
if (snippet) {
|
||||
debouncedUpdateSnippet(id, snippet.projectRef, {
|
||||
id,
|
||||
type: 'sql',
|
||||
name: snippet.snippet.name ?? 'Untitled',
|
||||
description: snippet.snippet.description ?? '',
|
||||
visibility: snippet.snippet.visibility ?? 'user',
|
||||
project_id: snippet.snippet.project_id ?? 0,
|
||||
owner_id: snippet.snippet.owner_id,
|
||||
folder_id: snippet.snippet.folder_id,
|
||||
content: {
|
||||
...snippet.snippet.content,
|
||||
content_id: id,
|
||||
favorite: snippet.snippet.favorite,
|
||||
},
|
||||
})
|
||||
sqlEditorState.needsSaving.delete(id)
|
||||
const {
|
||||
name,
|
||||
description,
|
||||
visibility,
|
||||
project_id,
|
||||
owner_id,
|
||||
folder_id,
|
||||
content,
|
||||
favorite,
|
||||
} = snippet.snippet
|
||||
|
||||
if (visibility === 'project' && !!folder_id) {
|
||||
toast.error('Shared snippet cannot be within a folder')
|
||||
} else {
|
||||
debouncedUpdateSnippet(id, snippet.projectRef, {
|
||||
id,
|
||||
type: 'sql',
|
||||
name: name ?? 'Untitled',
|
||||
description: description ?? '',
|
||||
visibility: visibility ?? 'user',
|
||||
project_id: project_id ?? 0,
|
||||
owner_id: owner_id,
|
||||
folder_id: folder_id,
|
||||
content: {
|
||||
...content,
|
||||
content_id: id,
|
||||
favorite: favorite,
|
||||
},
|
||||
})
|
||||
sqlEditorState.needsSaving.delete(id)
|
||||
}
|
||||
} else if (folder) {
|
||||
upsertFolder(id, folder.projectRef, folder.folder.name)
|
||||
sqlEditorState.needsSaving.delete(id)
|
||||
|
||||
Reference in new issue
Block a user