diff --git a/docs/tutorialkit.dev/src/content/docs/reference/configuration.mdx b/docs/tutorialkit.dev/src/content/docs/reference/configuration.mdx index c70ab5895..e57bfbca9 100644 --- a/docs/tutorialkit.dev/src/content/docs/reference/configuration.mdx +++ b/docs/tutorialkit.dev/src/content/docs/reference/configuration.mdx @@ -320,7 +320,7 @@ You can set terminal open by default by specifying the `open` value. An interactive terminal will disable the output redirect syntax by default. For instance, you cannot create a file `world.txt` with the contents `hello` using the command `echo hello > world.txt`. The reason is that this could disrupt the lesson if a user overwrites certain files. To allow output redirection, you can change the behavior with the `allowRedirects` setting. You can define this setting either per panel or for all panels at once. -Additionally, you may not want users to run arbitrary commands. For example, if you are creating a lesson about `vitest`, you could specify that the only command the user can run is `vitest` by providing a list of `allowCommands`. Any other command executed by the user will be blocked. You can define the `allowCommands` setting either per panel or for all panels at once. +Additionally, you may not want users to run arbitrary commands. For example, if you are creating a lesson about `vitest`, you could specify that the only command the user can run is `vitest` by providing a list of `allowCommands`. By default, the allowed commands are `ls` and `echo`. Providing a list of `allowCommands` will override these defaults, and specifying an empty list will allow all commands. Any other command executed by the user will be blocked. You can define the `allowCommands` setting either per panel or for all panels at once. By default, in every new lesson terminals start a new session. If you want to keep the terminal session between lessons, you can specify the `id` property for a given terminal panel and keep the same `id` across lessons. diff --git a/packages/runtime/src/webcontainer/terminal-config.spec.ts b/packages/runtime/src/webcontainer/terminal-config.spec.ts index 8dd2f851e..ae5a4a774 100644 --- a/packages/runtime/src/webcontainer/terminal-config.spec.ts +++ b/packages/runtime/src/webcontainer/terminal-config.spec.ts @@ -56,13 +56,13 @@ describe('TerminalConfig', () => { expect(config.panels[0].id).toBe('foo'); expect(config.panels[0].processOptions).toEqual({ allowRedirects: false, - allowCommands: undefined, + allowCommands: ['ls', 'echo'], }); expect(config.panels[1].title).toBe('Bar'); expect(config.panels[1].id).toBe('bar'); expect(config.panels[1].processOptions).toEqual({ allowRedirects: false, - allowCommands: undefined, + allowCommands: ['ls', 'echo'], }); }); diff --git a/packages/runtime/src/webcontainer/terminal-config.ts b/packages/runtime/src/webcontainer/terminal-config.ts index cdfb8afa4..4704005e8 100644 --- a/packages/runtime/src/webcontainer/terminal-config.ts +++ b/packages/runtime/src/webcontainer/terminal-config.ts @@ -200,6 +200,9 @@ export class TerminalPanel implements ITerminal { } } +// set the default commands for the terminal +const DEFAULT_COMMANDS = ['ls', 'echo']; + /** * Normalize the provided configuration to a configuration which is easier to parse. * @@ -232,6 +235,18 @@ function normalizeTerminalConfig(config?: TerminalSchema): NormalizedTerminalCon const panels: TerminalPanel[] = []; + const resolveAllowCommands = (globalCommands?: string[], panelCommands?: string[]): string[] | undefined => { + if (panelCommands === undefined) { + return globalCommands ?? DEFAULT_COMMANDS; + } + + if (Array.isArray(panelCommands) && panelCommands.length === 0) { + return undefined; + } + + return panelCommands; + }; + const options = { allowRedirects: config.allowRedirects, allowCommands: config.allowCommands, @@ -258,7 +273,7 @@ function normalizeTerminalConfig(config?: TerminalSchema): NormalizedTerminalCon id: panel.id, title: panel.title, allowRedirects: panel.allowRedirects ?? config.allowRedirects, - allowCommands: panel.allowCommands ?? config.allowCommands, + allowCommands: resolveAllowCommands(config.allowCommands, panel.allowCommands), }); }