-
Notifications
You must be signed in to change notification settings - Fork 252
fix(variables): validate variable keys before writing them #3155
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
Open
levivannoort
wants to merge
3
commits into
main
Choose a base branch
from
fix/variable-key-validation
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| import { expect, test } from 'vitest'; | ||
| import { | ||
| getVariableKeyError, | ||
| isValidVariableKey, | ||
| validateVariables, | ||
| VARIABLE_KEY_MAX_LENGTH, | ||
| VARIABLE_VALUE_MAX_LENGTH | ||
| } from '$lib/helpers/variables'; | ||
|
|
||
| test('accept keys that are valid environment variable names', () => { | ||
| expect(isValidVariableKey('APP_TEST')).toBe(true); | ||
| expect(isValidVariableKey('_PRIVATE')).toBe(true); | ||
| expect(isValidVariableKey('key1')).toBe(true); | ||
| expect(isValidVariableKey('a'.repeat(VARIABLE_KEY_MAX_LENGTH))).toBe(true); | ||
| }); | ||
|
|
||
| test('reject keys that cannot be used as environment variable names', () => { | ||
| expect(isValidVariableKey('MY-KEY')).toBe(false); | ||
| expect(isValidVariableKey('MY.KEY')).toBe(false); | ||
| expect(isValidVariableKey('MY KEY')).toBe(false); | ||
| expect(isValidVariableKey('9KEY')).toBe(false); | ||
| expect(isValidVariableKey('KÉY')).toBe(false); | ||
| expect(isValidVariableKey('KEY\t')).toBe(false); | ||
| expect(isValidVariableKey('')).toBe(false); | ||
| expect(isValidVariableKey('a'.repeat(VARIABLE_KEY_MAX_LENGTH + 1))).toBe(false); | ||
| }); | ||
|
|
||
| test('report a missing key separately from an invalid one', () => { | ||
| expect(getVariableKeyError('')).toEqual('Variable key is required'); | ||
| expect(getVariableKeyError('MY-KEY')).toContain('is invalid'); | ||
| expect(getVariableKeyError('a'.repeat(VARIABLE_KEY_MAX_LENGTH + 1))).toContain('longer than'); | ||
| expect(getVariableKeyError('APP_TEST')).toBeNull(); | ||
| }); | ||
|
|
||
| test('validate a list of variables and name the offending key', () => { | ||
| expect(validateVariables([{ key: 'APP_TEST', value: 'value' }])).toBeNull(); | ||
| expect(validateVariables([{ key: 'APP_TEST', value: '' }])).toBeNull(); | ||
|
|
||
| expect( | ||
| validateVariables([ | ||
| { key: 'APP_TEST', value: 'value' }, | ||
| { key: 'MY-KEY', value: 'value' } | ||
| ]) | ||
| ).toContain('MY-KEY'); | ||
|
|
||
| expect( | ||
| validateVariables([{ key: 'APP_TEST', value: 'v'.repeat(VARIABLE_VALUE_MAX_LENGTH + 1) }]) | ||
| ).toContain('APP_TEST'); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Wouldn’t this also validate keys that are already stored? 🤔 If a project contains a legacy key (examplews MY-KEY), updating only its value would fail here before sdkUpdateVariable(..., undefined, ...) is ever reached. Should we only validate keys for newly added variables and keep validating values for existing ones?
cc @greptile
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.
Good catch, but the concern is scoped to the wrong component. In
createVariableModal.svelte,validateVariablesis only called onnewVariables— the rows the user is currently entering in the form. The pre-existingvariablesprop is never passed through validation here, so legacy stored keys are safe.The concern is real in
updateVariableModal.sveltethough. There,pairis initialized fromselectedVar(the stored variable), andvalidateVariables([pair])runs unconditionally on submit — it doesn't check whetherpair.keyactually changed. So if a user opens the update modal on a legacyMY-KEYvariable to change only the value, the key validation fires and blocks them beforesdkUpdateVariable(withundefinedkey) is ever reached. That's the breakage the PR description says it fixes, but looking at the actual code inupdateVariableModal.sveltethe guard isn't there.The fix would be to skip key validation when the key is unchanged:
But
validateVariables→getVariableKeyErrorreturns'Variable key is required'for anundefinedkey, sovalidateVariableswould also need to treatkey === undefinedas "skip key check" (i.e. only validate value). Worth addressing before merge — as-is,updateVariableModal.sveltestill breaks value-only edits on any pre-existing invalid key.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.
Checked both create modals and both update modals — no change needed here, and the split you describe is what is already implemented.
Create modals (
lib/components/variables/createVariableModal.svelte,project-[region]-[project]/createVariableModal.svelte):validateVariablesonly ever receivesnewVariables, the rows being typed into the form. The pre-existingvariablesprop is never passed through it, so stored keys are untouched.Update modal (
project-[region]-[project]/updateVariablesModal.svelte) — this is the one reachable from the post-create variables table, and it already guards on the key having changed:so a value-only edit on a legacy
MY-KEYvalidates the value only, and dispatcheskey: undefinedso the API keeps the stored key.lib/components/variables/updateVariableModal.svelte(the singular one, which greptile pointed at) validates unconditionally, but as you noted in the other thread it is only reachable throughEnvironmentVariablesin the two create-flow configuration components, where the key is always user-entered.