What permissions does code.pyret.org ask for and why?
+
What permissions does {{APP_NAME}} ask for and why?
-
code.pyret.org asks for several permissions when you log in:
+
{{APP_NAME}} asks for several permissions when you log in:
@@ -59,16 +59,16 @@
Where are things stored in my Drive?
The site initially makes a single folder in your Google Drive, called
-code.pyret.org, and stores all of your programs there, with the
+{{APP_NAME}}, 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.pyret.org.compiled that is used for caching compiled copies
+{{APP_NAME}}.compiled that is used for caching compiled copies
of programs.
If you publish programs, the site creates a new folder, called
-code.pyret.org.shared, and makes publicly-readable
+{{APP_NAME}}.shared, and makes publicly-readable
copies 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.
@@ -76,11 +76,11 @@
Where are things stored in my Drive?
contents.
-
How can I remove the access code.pyret.org has to my data?
+
How can I remove the access {{APP_NAME}} has to my data?
You can always go to https://security.google.com/settings/security/permissions?pli=1
-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 not be
deleted if you do so. You can always manually delete the folder and its
contents yourself.
@@ -98,7 +98,7 @@
How can I see old versions of my programs?
What information is sent back to the Pyret team?
-
We collect basic information about your use of code.pyret.org to help us
+
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
diff --git a/src/web/ide.html b/src/web/ide.html
index 03b19106..1e9aa289 100644
--- a/src/web/ide.html
+++ b/src/web/ide.html
@@ -2,7 +2,7 @@
diff --git a/src/web/js/dashboard/config.js b/src/web/js/dashboard/config.js
index 75c385bb..5363e354 100644
--- a/src/web/js/dashboard/config.js
+++ b/src/web/js/dashboard/config.js
@@ -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';
diff --git a/src/web/js/events.js b/src/web/js/events.js
index 9cc00264..9b46ad02 100644
--- a/src/web/js/events.js
+++ b/src/web/js/events.js
@@ -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 {
diff --git a/src/web/privacy.html b/src/web/privacy.html
index 31c336ee..b928b2be 100644
--- a/src/web/privacy.html
+++ b/src/web/privacy.html
@@ -1,4 +1,4 @@
-
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").
+
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").
Personal identification information
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.
@@ -10,7 +10,7 @@
Web browser cookies
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.
How we use collected information
-
code.pyret.org may collect and use Users personal information for the following purposes:
+
{{APP_NAME}} may collect and use Users personal information for the following purposes:
To run and operate our Site
@@ -37,7 +37,7 @@
Sharing your personal information
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.
Changes to this privacy policy
-
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.
+
{{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.
Your acceptance of these terms
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 using the generator at http://PrivacyPolicies.com.
diff --git a/src/web/share.template.html b/src/web/share.template.html
index 75cf0a2a..157f1d91 100644
--- a/src/web/share.template.html
+++ b/src/web/share.template.html
@@ -2,7 +2,7 @@
- code.pyret.org
+ {{APP_NAME}}
diff --git a/test/static-pages.js b/test/static-pages.js
new file mode 100644
index 00000000..bc3bb7e4
--- /dev/null
+++ b/test/static-pages.js
@@ -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);
+ });
+ });
+ });
+});
diff --git a/webpack.config.js b/webpack.config.js
index 0b0043bb..ba51ebf2 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -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 },