What permissions does code.pyret.org ask for and why?
Know who you are on Google and View your email address:
The site needs to know your Google identity because this allows us to give
persistent access to saving to Drive that doesn't expire or require popping up
-new windows while you're editing.
-
-
Manage your photos and videos and View the photos, videos, and
-albums in your Google Drive: This is used to import images into programs
-from your Drive (which can be useful for customizing games, for example).
-
-
-
View and manage your spreadsheets on Google Drive: This enables
-importing tables and working with data sources in your Drive.
+new windows while you're editing.
Add itself to Google Drive: This lets you right-click on Pyret
programs in Google Drive and "Open with Pyret."
diff --git a/src/web/js/cpo-main.js b/src/web/js/cpo-main.js
index 33f02323..41eedfa1 100644
--- a/src/web/js/cpo-main.js
+++ b/src/web/js/cpo-main.js
@@ -150,6 +150,15 @@
// NOTE(joe): this function just allocates a closure, so it's stack-safe
var onCompile = gmf(cpo, "make-on-compile").app(runtime.makeFunction(saveGDriveCachedFile, "save-gdrive-cached-file"));
+ function maybeAppendSlash(s) {
+ if(s.endsWith("/")) { return s; }
+ return s + "/";
+ }
+
+ function urlResolve(path, base) {
+ return new URL(path, base).href;
+ }
+
// NOTE(joe/ben): this function _used_ to be trivially stack safe, but files
// need to resolve their absolute path to calculate their URI, which
// requires an RPC, so this function is no-longer trivially flat
@@ -198,7 +207,7 @@
return arr[0];
}
else if (protocol === "url-file") {
- return arr[0] + "/" + arr[1];
+ return urlResolve(arr[1], maybeAppendSlash(arr[0]));
}
else {
console.error("Unknown import: ", dependency);
@@ -256,7 +265,7 @@
return runtime.getField(runtime.getField(urlLoc, "values"), "url-locator").app(arr[0], replGlobals);
}
else if (protocol === "url-file") {
- const fullUrl = arr[0] + "/" + arr[1];
+ const fullUrl = urlResolve(arr[1], maybeAppendSlash(arr[0]));
switch(urlFileMode) {
case "all-remote":
fetch(fullUrl).then(async (response) => {
diff --git a/src/web/js/dashboard/StudentDashboard.js b/src/web/js/dashboard/StudentDashboard.js
index 1fbd9b4d..b64edeb7 100644
--- a/src/web/js/dashboard/StudentDashboard.js
+++ b/src/web/js/dashboard/StudentDashboard.js
@@ -228,7 +228,7 @@ class StudentDashboard extends Component {