Skip to content

Conversation

@snickell
Copy link
Contributor

@snickell snickell commented Nov 14, 2025

Previously we use https://preview.codeprojects.org as the domain to serve ALL projects, directed into an iframe embedded within a https://studio.code.org page. A service worker was then used to intercept requests to preview.codeprojects.org, and potentially serve in-memory copies as the user edits, making preview updates fast and not require an HTTP roundtrip to our server.

However, there's ONE service worker for all pages in this scenario, and multiple open projects presented an issue: how to identify which project contents to return from the service worker?

By moving to a URL like https://${channelID}.preview.codeprojects.org we solve the problem for our service workers AND it means each student-authored website is served from its own unique domain, solving possible student data exfiltration issues by malicious projects.

TODO

  • Fix bug with existing level content
  • Remove definitions for preview.

@snickell snickell changed the title WIP weblab2: allow ${channelId}.preview.codeprojects.org subdomains for projects weblab2: use subdomains for project preview Nov 26, 2025
@snickell
Copy link
Contributor Author

Deployed to a fullstack and was able to confirm that both the single editor and two project editing case works on this branch at the current point:
image (9)

Two projects open now works without hacks:
image (10)

@molly-moen molly-moen self-requested a review December 1, 2025 17:29
@snickell snickell marked this pull request as ready for review December 2, 2025 15:19
@snickell snickell requested a review from a team as a code owner December 2, 2025 15:19
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 39 to 43
const port =
'localhost' === environmentKey && location.port
? `:${location.port}`
: '';
return `${location.protocol}//${normalizedChannelId}.preview.${subdomain}codeprojects.org${port}`;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Channel IDs used verbatim as subdomains

The preview URL is now built as ${normalizedChannelId}.preview... without any sanitization. Channel IDs are produced via Base64.urlsafe_encode64 (see storage_encrypt_channel_id), which frequently yields underscores; underscores are not legal in DNS host labels, so any project whose channel ID includes _ will resolve to an invalid host and the preview iframe/service worker will fail to load. A DNS-safe mapping (e.g., base32/hex or encoding) is needed before using channel IDs as subdomains.

Useful? React with 👍 / 👎.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@snickell I updated the channel id normalization to remove underscores. I think the UUID change will allow us to get rid of the normalization logic.

@sureshc
Copy link
Contributor

sureshc commented Dec 3, 2025

heads up that @alex-m-brown is working to switch projects to use a UUID instead of the "channel id" (encrypted project id + storage id) in #69293

@molly-moen molly-moen requested a review from a team December 16, 2025 18:34
Copy link
Contributor

@fisher-alice fisher-alice left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Learned a lot from this PR and #69422!

const prefix =
useLocalPrefixOverride && isLocalhost
? 'localtesting'
: normalizedChannelId;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just confirming my understanding that this resolves the TODO in weblab2_project_service_worker.js.

// TODO: Right now if you have multiple tabs open to different projects, the service worker will
// serve the most recent files to each tab, which means one tab will show the other tab's project.
// We are investigating solutions to this, such as registering a separate service worker per project via a subdomain.
// Do not make the service worker the default way of serving files until this is resolved.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, if the same project is open in different tabs, would they always show the same file? I can't get this to currently work locally so just curious.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the same project is open in different tabs we will force reload a tab anyway, so I'm not too worried about that scenario. We generally don't support it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re: the todo, yes it resolves it! I'll remove the todo as a follow-up

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the follow-up!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the same project is open in different tabs we will force reload a tab anyway, so I'm not too worried about that scenario. We generally don't support it.

Oh interesting - thanks!

@molly-moen molly-moen merged commit c2b2519 into staging Dec 16, 2025
6 checks passed
@molly-moen molly-moen deleted the preview-subdomains branch December 16, 2025 22:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants