Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.embed
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,7 @@ CURRENT_PYRET_RELEASE=""
PYRET="./js/cpo-main.jarr.js"
POSTMESSAGE_ORIGIN="*"
SHARED_FETCH_SERVER="https://code.pyret.org"
APP_NAME=code.pyret.org
APP_DOMAIN=code.pyret.org
URL_FILE_MODE="all-remote"
IMAGE_PROXY_BYPASS="true"
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,7 @@ PORT=4999
NODE_ENV=development
POSTMESSAGE_ORIGIN="http://localhost:3000"
SHARED_FETCH_SERVER="https://code.pyret.org"
APP_NAME=code.pyret.org
APP_DOMAIN=code.pyret.org
URL_FILE_MODE="all-remote"
IMAGE_PROXY_BYPASS="set to true to avoid image proxying through BASE_URL/downloadImg (the default)"
2 changes: 2 additions & 0 deletions .github/workflows/makefile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ jobs:
echo "URL_FILE_MODE=all-remote" >> $GITHUB_ENV
echo "IMAGE_PROXY_BYPASS=true" >> $GITHUB_ENV
echo "POSTMESSAGE_ORIGIN=*" >> $GITHUB_ENV
echo "APP_NAME=code.pyret.org" >> $GITHUB_ENV
echo "APP_DOMAIN=code.pyret.org" >> $GITHUB_ENV

- name: Start application server
run: |
Expand Down
2 changes: 1 addition & 1 deletion src/scripts/get-image.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ function saveBase64PngToFile(base64, filename) {
}

async function go(example) {
const fetchresult = browser.get("https://code.pyret.org/editor");
const fetchresult = browser.get("https://" + process.env.APP_DOMAIN + "/editor");
const result = await waitForPyretLoad(browser);
const result2 = await setDefinitionsEvalAndWait(browser, example.code, { typeCheck: false });
browser.wait(webdriver.until.elementLocated(webdriver.By.css("canvas")), 10000);
Expand Down
19 changes: 12 additions & 7 deletions src/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ var SHAREURL_PROXY_MAX_BYTES = 1 * 1024 * 1024; // 1 MB
var SHAREURL_PROXY_TIMEOUT_MS = 10 * 1000; // 10 s

function start(config, onServerReady) {
var APP_NAME = process.env.APP_NAME || "code.pyret.org";
var APP_DOMAIN = process.env.APP_DOMAIN || "code.pyret.org";

var defaultOpts = {
PYRET: process.env.PYRET,
BASE_URL: config.baseUrl,
Expand All @@ -30,7 +33,9 @@ function start(config, onServerReady) {
LOG_USER: config.logUser,
GIT_REV : config.gitRev,
GIT_BRANCH: config.gitBranch,
POSTMESSAGE_ORIGIN: process.env.POSTMESSAGE_ORIGIN
POSTMESSAGE_ORIGIN: process.env.POSTMESSAGE_ORIGIN,
APP_NAME: APP_NAME,
APP_DOMAIN: APP_DOMAIN,
};
var express = require('express');
var cookieSession = require('cookie-session');
Expand Down Expand Up @@ -98,7 +103,7 @@ function start(config, onServerReady) {

app.use(cookieSession({
secret: config.sessionSecret,
key: "code.pyret.org",
key: APP_NAME,

sameSite: 'lax'
}));
Expand All @@ -123,12 +128,12 @@ function start(config, onServerReady) {

app.use(csrf());

app.get("/close.html", function(_, res) { res.render("close.html"); });
app.get("/faq.html", function(_, res) { res.render("faq.html"); });
app.get("/privacy.html", function(_, res) { res.render("privacy.html"); });
app.get("/privacy/", function(_, res) { res.render("privacy.html"); });
app.get("/close.html", function(_, res) { res.render("close.html", defaultOpts); });
app.get("/faq.html", function(_, res) { res.render("faq.html", defaultOpts); });
app.get("/privacy.html", function(_, res) { res.render("privacy.html", defaultOpts); });
app.get("/privacy/", function(_, res) { res.render("privacy.html", defaultOpts); });

app.get("/faq", function(_, res) { res.render("faq.html"); });
app.get("/faq", function(_, res) { res.render("faq.html", defaultOpts); });

app.get("/", function(req, res) {
var content = loggedIn(req) ? "My Programs" : "Log In";
Expand Down
4 changes: 2 additions & 2 deletions src/web/blocks.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>code.pyret.org</title>
<title>{{APP_NAME}}</title>
<link crossorigin="anonymous" rel="preload" href="{{&PYRET}}" as="script">
<script>window.PYRET = "{{&PYRET}}";</script>
<script>window.PYRET = "{{&PYRET}}"; window.APP_NAME = "{{APP_NAME}}"; window.APP_DOMAIN = "{{APP_DOMAIN}}";</script>
<link rel="stylesheet" href="/css/reset.css" />
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Fira+Mono:400,700" />
Expand Down
6 changes: 3 additions & 3 deletions src/web/editor.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>code.pyret.org</title>
<title>{{APP_NAME}}</title>
<link crossorigin="anonymous" rel="preload" href="{{&PYRET}}" as="script">
<script>window.PYRET = "{{&PYRET}}";</script>
<script>window.PYRET = "{{&PYRET}}"; window.APP_NAME = "{{APP_NAME}}"; window.APP_DOMAIN = "{{APP_DOMAIN}}";</script>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we need the & here? Any escaping that we should include/avoid? Should probably justify the difference.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

oooh, good call.

<link rel="stylesheet" href="{{ &BASE_URL }}/css/reset.css" />
<link rel="stylesheet" href="{{ &BASE_URL }}/css/smoothness-jquery-ui.css" />
<link rel="stylesheet" href="{{ &BASE_URL }}/css/fira-mono.css" />
Expand Down Expand Up @@ -156,7 +156,7 @@ <h2 id="menutitle" class="screenreader-only">Navigation Controls</h2>
aria-label="Contribute detailed usage information"/>
<label for="detailed-logging" id="detailed-logging-label">
Contribute detailed usage information.</label>
<a href="https://code.pyret.org/faq/" target="_blank" rel="noopener noreferrer" class="focusable info-btn" role="menuitem" tabindex="-1"
<a href="https://{{APP_DOMAIN}}/faq/" target="_blank" rel="noopener noreferrer" class="focusable info-btn" role="menuitem" tabindex="-1"
id="detailed-logging-learn-more"
title="Learn More" aria-label="Learn More">?</a>
</span>
Expand Down
20 changes: 10 additions & 10 deletions src/web/faq.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>code.pyret.org</title>
<title>{{APP_NAME}}</title>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Dumb question: does faq get templated by server.js? I forget which pages actually get all the template variables. Is it all of them?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Looks like it doesn't:
app.get("/close.html", function(_, res) { res.render("close.html"); })

Is there any reason not to pass defaultOpts to all of them?

<link rel="stylesheet" href="/css/reset.css" />
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href="/css/shared.css" />
Expand All @@ -27,15 +27,15 @@
<body>
<div id="header">
<a id="logo" href="http://www.pyret.org/"></a>
<h1>Information <code>code.pyret.org</code> Uses and Stores</h1>
<h1>Information <code>{{APP_NAME}}</code> Uses and Stores</h1>
</div>
<div id="toolbar">
</div>
<div id="main" style="width: 40em; padding-left: 2em;">

<h3>What permissions does code.pyret.org ask for and why?</h3>
<h3>What permissions does {{APP_NAME}} ask for and why?</h3>

<p>code.pyret.org asks for several permissions when you log in:</p>
<p>{{APP_NAME}} asks for several permissions when you log in:</p>

<ul>

Expand All @@ -59,28 +59,28 @@ <h3>Where are things stored in my Drive?</h3>

<p>
The site initially makes a single folder in your Google Drive, called
<code>code.pyret.org</code>, and stores all of your programs there, with the
<code>{{APP_NAME}}</code>, and stores all of your programs there, with the
names you choose for them. They are all created with you as the owner, and
private to your account. There is also a directory called
<code>code.pyret.org.compiled</code> that is used for caching compiled copies
<code>{{APP_NAME}}.compiled</code> that is used for caching compiled copies
of programs.
</p>

<p>
If you <em>publish</em> programs, the site creates a new folder, called
<code>code.pyret.org.shared</code>, and makes <em>publicly-readable
<code>{{APP_NAME}}.shared</code>, and makes <em>publicly-readable
copies</em> of programs you publish in that directory. If you delete this
files in this folder, links for those programs you have shared with others
will stop working, but any copies others have made will be theirs to keep.
Each time you publish a program, a new copy is created from its current
contents.
</p>

<h3>How can I remove the access code.pyret.org has to my data?</h3>
<h3>How can I remove the access {{APP_NAME}} has to my data?</h3>

<p> You can always go to <a
href="https://security.google.com/settings/security/permissions?pli=1">https://security.google.com/settings/security/permissions?pli=1</a>
and remove all access that code.pyret.org has to your account.
and remove all access that {{APP_NAME}} has to your account.
Your programs and the created folders will <em>not</em> be
deleted if you do so. You can always manually delete the folder and its
contents yourself.</p>
Expand All @@ -98,7 +98,7 @@ <h3>How can I see old versions of my programs?</h3>

<h3 id="logging">What information is sent back to the Pyret team?</h3>

<p>We collect basic information about your use of code.pyret.org to help us
<p>We collect basic information about your use of {{APP_NAME}} to help us
improve the language and editor, and enable some debugging. We send back
information about errors, authentication, whether features such as the
type-checker are used, and preferences (such as which mode you choose to
Expand Down
2 changes: 1 addition & 1 deletion src/web/ide.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>code.pyret.org</title>
<title>{{APP_NAME}}</title>
<link rel="icon" type="image/png" href="/img/pyret-icon.png">
</head>
<body>
Expand Down
2 changes: 1 addition & 1 deletion src/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>code.pyret.org</title>
<title>{{APP_NAME}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="/img/pyret-icon.png">
<link rel="prefetch" href="{{&PYRET}}" as="script">
Expand Down
2 changes: 1 addition & 1 deletion src/web/js/authenticate-storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ window.handleClientLoad = function handleClientLoad(apiKey, publicOnly) {
return;
}
gapi.client.setApiKey(apiKey);
var api = createProgramCollectionAPI("code.pyret.org", true, publicOnly);
var api = createProgramCollectionAPI(window.APP_NAME, true, publicOnly);

api.then(function(api) {
storageAPIDeferred.resolve(api);
Expand Down
4 changes: 2 additions & 2 deletions src/web/js/beforeBlocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ $(function() {
$("#connectButton").attr("tabIndex", "-1");
//$("#topTierUl").attr("tabIndex", "0");
getTopTierMenuitems();
storageAPI = createProgramCollectionAPI("code.pyret.org", false);
storageAPI = createProgramCollectionAPI(process.env.APP_NAME, false);
storageAPI.then(function(api) {
api.collection.then(function() {
$(".loginOnly").show();
Expand Down Expand Up @@ -419,7 +419,7 @@ $(function() {
});

function setTitle(progName) {
document.title = progName + " - code.pyret.org";
document.title = progName + " - " + process.env.APP_NAME;
$("#showFilename").text("File: " + progName);
}
CPO.setTitle = setTitle;
Expand Down
4 changes: 2 additions & 2 deletions src/web/js/beforePyret.js
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ $(function() {
$("#connectButton").attr("tabIndex", "-1");
//$("#topTierUl").attr("tabIndex", "0");
getTopTierMenuitems();
storageAPI = createProgramCollectionAPI("code.pyret.org", false);
storageAPI = createProgramCollectionAPI(process.env.APP_NAME, false);
storageAPI.then(function(api) {
api.collection.then(function() {
$(".loginOnly").show();
Expand Down Expand Up @@ -580,7 +580,7 @@ $(function() {
}

function setTitle(progName) {
document.title = progName + " - code.pyret.org";
document.title = progName + " - " + process.env.APP_NAME;
$("#showFilename").text("File: " + progName);
}
CPO.setTitle = setTitle;
Expand Down
2 changes: 1 addition & 1 deletion src/web/js/dashboard/StudentDashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ class StudentDashboard extends Component {
</div>
<div className='footer middle'>
<p className='right'>
<a target="_blank" href="https://www.pyret.org">pyret.org</a> | <a target="_blank" href="https://code.pyret.org/faq/">Policies</a> | <a target="_blank" href="https://www.github.com/brownplt/code.pyret.org">Software</a></p>
<a target="_blank" href="https://www.pyret.org">pyret.org</a> | <a target="_blank" href={"https://" + process.env.APP_DOMAIN + "/faq/"}>Policies</a> | <a target="_blank" href="https://www.github.com/brownplt/code.pyret.org">Software</a></p>
</div>

</div>
Expand Down
2 changes: 1 addition & 1 deletion src/web/js/dashboard/config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// App name in *Title Case*.
export const APP_NAME = 'code.pyret.org';
export const APP_NAME = process.env.APP_NAME;

// File extension of code files for this app.
export const FILE_EXT = 'arr';
Expand Down
2 changes: 1 addition & 1 deletion src/web/js/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ function makeEvents(config) {
return reset(initialState);
}
// This means we got a CPO link as the initial state.
if((typeof APP_BASE_URL === 'string' && APP_BASE_URL !== "" && message.state.startsWith(APP_BASE_URL)) || message.state.startsWith("https://code.pyret.org")) {
if((typeof APP_BASE_URL === 'string' && APP_BASE_URL !== "" && message.state.startsWith(APP_BASE_URL)) || message.state.startsWith("https://" + window.APP_DOMAIN)) {
return resetFromShare(message.state);
}
try {
Expand Down
6 changes: 3 additions & 3 deletions src/web/privacy.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<p>This Privacy Policy governs the manner in which code.pyret.org collects, uses, maintains and discloses information collected from users (each, a "User") of the https://code.pyret.org website ("Site").</p>
<p>This Privacy Policy governs the manner in which {{APP_NAME}} collects, uses, maintains and discloses information collected from users (each, a "User") of the https://{{APP_DOMAIN}} website ("Site").</p>

<h3>Personal identification information</h3>
<p>We may collect personal identification information from Users in a variety of ways in connection with activities, services, features or resources we make available on our Site. Users may visit our Site anonymously. We will collect personal identification information from Users only if they voluntarily submit such information to us. Users can always refuse to supply personally identification information, except that it may prevent them from engaging in certain Site related activities.</p>
Expand All @@ -10,7 +10,7 @@ <h3>Web browser cookies</h3>
<p>Our Site may use "cookies" to enhance User experience. User's web browser places cookies on their hard drive for record-keeping purposes and sometimes to track information about them. User may choose to set their web browser to refuse cookies, or to alert you when cookies are being sent. If they do so, note that some parts of the Site may not function properly.</p>

<h3>How we use collected information</h3>
<p>code.pyret.org may collect and use Users personal information for the following purposes:</p>
<p>{{APP_NAME}} may collect and use Users personal information for the following purposes:</p>
<ul>
<li>
<i>To run and operate our Site</i><br/>
Expand All @@ -37,7 +37,7 @@ <h3>Sharing your personal information</h3>
<p>We do not sell, trade, or rent Users personal identification information to others. We may share generic aggregated demographic information not linked to any personal identification information regarding visitors and users with our business partners, trusted affiliates and advertisers for the purposes outlined above. </p>

<h3>Changes to this privacy policy</h3>
<p>code.pyret.org has the discretion to update this privacy policy at any time. When we do, we will revise the updated date at the bottom of this page. We encourage Users to frequently check this page for any changes to stay informed about how we are helping to protect the personal information we collect. You acknowledge and agree that it is your responsibility to review this privacy policy periodically and become aware of modifications.</p>
<p>{{APP_NAME}} has the discretion to update this privacy policy at any time. When we do, we will revise the updated date at the bottom of this page. We encourage Users to frequently check this page for any changes to stay informed about how we are helping to protect the personal information we collect. You acknowledge and agree that it is your responsibility to review this privacy policy periodically and become aware of modifications.</p>

<h3>Your acceptance of these terms</h3>
<p>By using this Site, you signify your acceptance of this policy. If you do not agree to this policy, please do not use our Site. Your continued use of the Site following the posting of changes to this policy will be deemed your acceptance of those changes. This privacy policy was built <a href="http://privacypolicies.com/" target="_blank">using the generator at http://PrivacyPolicies.com</a>.</p>
Expand Down
2 changes: 1 addition & 1 deletion src/web/share.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>code.pyret.org</title>
<title>{{APP_NAME}}</title>
<link rel="stylesheet" href="/css/reset.css" />
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href="/css/shared.css" />
Expand Down
66 changes: 66 additions & 0 deletions test/static-pages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
var assert = require("assert");
var tester = require("../test-util/util.js");
var webdriver = require("selenium-webdriver");

// Add endpoints here to extend template-variable checking to more static pages
var static_pages = [
"/faq",
];

describe("Make sure template variables are used in static pages", function() {
static_pages.forEach(function(endpoint) {
describe(endpoint, function() {
beforeEach(tester.setup);
afterEach(tester.teardown);

it("should substitute APP_NAME and APP_DOMAIN", function(done) {
this.timeout(20000);
var self = this;

self.browser.get(self.base + endpoint);

// Verify the page title does not contain raw Mustache tokens
self.browser.getTitle().then(function(title) {
assert.ok(
!title.includes("{{APP_NAME}}"),
endpoint + " title should not contain unsubstituted {{APP_NAME}}, got: " + title
);
assert.ok(
title.length > 0,
endpoint + " title should not be empty"
);
});

// Verify the page body does not contain any raw Mustache tokens
self.browser.findElement(webdriver.By.tagName("body")).getText().then(function(bodyText) {
assert.ok(
!bodyText.includes("{{APP_NAME}}"),
endpoint + " body should not contain unsubstituted {{APP_NAME}}"
);
assert.ok(
!bodyText.includes("{{APP_DOMAIN}}"),
endpoint + " body should not contain unsubstituted {{APP_DOMAIN}}"
);
assert.ok(
!bodyText.includes("{{"),
endpoint + " body should not contain any unsubstituted Mustache tokens"
);
});

// Verify that the actual APP_NAME value appears somewhere on the page
// (Since .env sets APP_NAME=TESTING, this confirms real substitution occurred)
var appName = process.env.APP_NAME;
if (appName) {
self.browser.findElement(webdriver.By.tagName("body")).getText().then(function(bodyText) {
assert.ok(
bodyText.includes(appName),
endpoint + " body should contain the APP_NAME value '" + appName + "'"
);
});
}

self.browser.call(done);
});
});
});
});
2 changes: 2 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ module.exports = {
'process.env.PYRET_BACKUP': JSON.stringify(process.env.PYRET_BACKUP),
'process.env.BASE_URL': JSON.stringify(process.env.BASE_URL),
'process.env.CURRENT_PYRET_RELEASE': JSON.stringify(process.env.CURRENT_PYRET_RELEASE),
'process.env.APP_NAME': JSON.stringify(process.env.APP_NAME || "code.pyret.org"),
'process.env.APP_DOMAIN': JSON.stringify(process.env.APP_DOMAIN || "code.pyret.org"),
}),
],
optimization: { minimize: IS_PRODUCTION },
Expand Down
Loading