mirror of
https://github.com/compiler-explorer/compiler-explorer.git
synced 2025-12-27 09:23:52 -05:00
Improvements to policy handling (#3595)
* Use webpack loaders to generate both the pug output and the SHA256 hash of it * Uniformly use pug for HTML templating * Policy hashes are entirely client-side * No longer need to have the policy documents available to the server side
This commit is contained in:
7
app.js
7
app.js
@@ -657,13 +657,6 @@ async function main() {
|
||||
);
|
||||
};
|
||||
|
||||
// Always serve the generated context directly from the distPath.
|
||||
router.use(
|
||||
'/static/generated',
|
||||
express.static(path.join(distPath, 'static', 'generated'), {
|
||||
maxAge: staticMaxAgeSecs * 1000,
|
||||
}),
|
||||
);
|
||||
await (isDevMode() ? setupWebPackDevMiddleware(router) : setupStaticMiddleware(router));
|
||||
|
||||
morgan.token('gdpr_ip', req => (req.ip ? utils.anonymizeIp(req.ip) : ''));
|
||||
|
||||
30
etc/scripts/parsed_pug_file.js
Normal file
30
etc/scripts/parsed_pug_file.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import {execSync} from 'child_process';
|
||||
import {getHashDigest} from 'loader-utils';
|
||||
import * as pug from 'pug';
|
||||
|
||||
function execGit(command) {
|
||||
const gitResult = execSync(command);
|
||||
if (!gitResult) {
|
||||
throw new Error(`Failed to execute ${command}`);
|
||||
}
|
||||
return gitResult.toString();
|
||||
}
|
||||
|
||||
const gitChanges = execGit('git log --date=local --after="3 months ago" "--grep=(#[0-9]*)" --oneline')
|
||||
.split('\n')
|
||||
.map(line => line.match(/(?<hash>\w+) (?<description>.*)/))
|
||||
.filter(x => x)
|
||||
.map(match => match.groups);
|
||||
|
||||
export default function(content) {
|
||||
const filename = this.resourcePath;
|
||||
const lastTime = execGit(`git log -1 --format=%cd "${filename}"`).trimEnd();
|
||||
const lastCommit = execGit(`git log -1 --format=%h "${filename}"`).trimEnd();
|
||||
const compiled = pug.compile(content.toString(), {filename});
|
||||
const source = compiled({gitChanges, lastTime, lastCommit});
|
||||
const result = {
|
||||
hash: getHashDigest(source, 'sha256', 'hex', 16),
|
||||
text: source.toString(),
|
||||
};
|
||||
return `export default ${JSON.stringify(result)};`;
|
||||
}
|
||||
@@ -30,9 +30,7 @@ import _ from 'underscore';
|
||||
|
||||
import {logger} from './logger';
|
||||
import {getToolTypeByKey} from './tooling';
|
||||
import {asSafeVer, countOccurrences, getHash, resolvePathFromAppRoot, splitArguments} from './utils';
|
||||
|
||||
const HashVersion = 'Compiler Explorer Policies Version 1';
|
||||
import {asSafeVer, getHash, splitArguments} from './utils';
|
||||
|
||||
/***
|
||||
* Handles the setup of the options object passed on each page request
|
||||
@@ -113,21 +111,10 @@ export class ClientOptionsHandler {
|
||||
policies: {
|
||||
cookies: {
|
||||
enabled: cookiePolicyEnabled,
|
||||
hash: cookiePolicyEnabled
|
||||
? ClientOptionsHandler.getFileHash(
|
||||
resolvePathFromAppRoot('static', 'generated', 'cookies.html'),
|
||||
)
|
||||
: null,
|
||||
key: 'cookie_status',
|
||||
},
|
||||
privacy: {
|
||||
enabled: privacyPolicyEnabled,
|
||||
hash: privacyPolicyEnabled
|
||||
? ClientOptionsHandler.getFileHash(
|
||||
resolvePathFromAppRoot('static', 'generated', 'privacy.html'),
|
||||
)
|
||||
: null,
|
||||
// How we store this privacy hash on the local storage
|
||||
key: 'privacy_status',
|
||||
},
|
||||
},
|
||||
@@ -390,13 +377,4 @@ export class ClientOptionsHandler {
|
||||
getHash() {
|
||||
return this.optionsHash;
|
||||
}
|
||||
|
||||
static getFileHash(path) {
|
||||
if (!fs.existsSync(path)) {
|
||||
logger.error(`File ${path} requested for hashing not found`);
|
||||
// Should we throw? What should happen here?
|
||||
}
|
||||
|
||||
return getHash(fs.readFileSync(path, 'utf-8'), HashVersion);
|
||||
}
|
||||
}
|
||||
|
||||
76
package-lock.json
generated
76
package-lock.json
generated
@@ -29,7 +29,6 @@
|
||||
"file-saver": "^2.0.5",
|
||||
"fs-extra": "^10.0.0",
|
||||
"golden-layout": "^1.5.9",
|
||||
"handlebars": "^4.7.7",
|
||||
"html-loader": "^3.0.1",
|
||||
"http-proxy": "^1.18.1",
|
||||
"husky": "^7.0.4",
|
||||
@@ -6927,34 +6926,6 @@
|
||||
"integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/handlebars": {
|
||||
"version": "4.7.7",
|
||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
|
||||
"integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.5",
|
||||
"neo-async": "^2.6.0",
|
||||
"source-map": "^0.6.1",
|
||||
"wordwrap": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"handlebars": "bin/handlebars"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.7"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"uglify-js": "^3.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/handlebars/node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
@@ -14039,18 +14010,6 @@
|
||||
"node": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uglify-js": {
|
||||
"version": "3.15.4",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.4.tgz",
|
||||
"integrity": "sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA==",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"uglifyjs": "bin/uglifyjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unbox-primitive": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
|
||||
@@ -15075,11 +15034,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wordwrap": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
|
||||
},
|
||||
"node_modules/workerpool": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz",
|
||||
@@ -20525,25 +20479,6 @@
|
||||
"integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==",
|
||||
"dev": true
|
||||
},
|
||||
"handlebars": {
|
||||
"version": "4.7.7",
|
||||
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
|
||||
"integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
|
||||
"requires": {
|
||||
"minimist": "^1.2.5",
|
||||
"neo-async": "^2.6.0",
|
||||
"source-map": "^0.6.1",
|
||||
"uglify-js": "^3.1.4",
|
||||
"wordwrap": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
@@ -25833,12 +25768,6 @@
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz",
|
||||
"integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg=="
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "3.15.4",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.4.tgz",
|
||||
"integrity": "sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA==",
|
||||
"optional": true
|
||||
},
|
||||
"unbox-primitive": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz",
|
||||
@@ -26588,11 +26517,6 @@
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
|
||||
},
|
||||
"wordwrap": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
|
||||
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
|
||||
},
|
||||
"workerpool": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz",
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
"file-saver": "^2.0.5",
|
||||
"fs-extra": "^10.0.0",
|
||||
"golden-layout": "^1.5.9",
|
||||
"handlebars": "^4.7.7",
|
||||
"html-loader": "^3.0.1",
|
||||
"http-proxy": "^1.18.1",
|
||||
"husky": "^7.0.4",
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
<div class="commits-list">
|
||||
{{#each gitChanges}}
|
||||
<div class="row commit-entry">
|
||||
<div class="col-sm-12">
|
||||
<a href="https://github.com/compiler-explorer/compiler-explorer/commit/{{hash}}" rel="noreferrer noopener" target="_blank">{{description}}</a>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
6
static/generated/changelog.pug
Normal file
6
static/generated/changelog.pug
Normal file
@@ -0,0 +1,6 @@
|
||||
div.commits-list
|
||||
each change in gitChanges
|
||||
div.row.commit-entry
|
||||
div.col-sm-12
|
||||
a(href="https://github.com/compiler-explorer/compiler-explorer/commit/#{change.hash}"
|
||||
rel="noreferrer noopener" target="_blank") #{change.description}
|
||||
@@ -1,78 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<!--
|
||||
Be aware: modifying this file in any way will cause a pop-up to users telling them the cookie policy has changed.
|
||||
-->
|
||||
|
||||
<html lang="en">
|
||||
<body>
|
||||
|
||||
<!--
|
||||
No need to update this! It's done by the build process.
|
||||
-->
|
||||
<span id="last-changed">
|
||||
Last changed on: <time id="changed-date" datetime="{{lastTime}}">{{lastTime}}</time>
|
||||
<i>
|
||||
(<a href="https://github.com/compiler-explorer/compiler-explorer/commit/{{lastCommit}}" target="_blank">diff</a>)
|
||||
</i>
|
||||
</span>
|
||||
|
||||
<h2>Compiler Explorer Cookie Policy</h2>
|
||||
|
||||
<p>
|
||||
Browsers support the storing and sending back of small text files called "Cookies". These cookie files can be used
|
||||
(amongst other things) to help track the usage of a website. See
|
||||
<a href="https://developer.mozilla.org/docs/Web/HTTP/Cookies" target="_blank" rel="noreferrer noopener">the Mozilla
|
||||
description of cookies</a> for more details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Compiler Explorer uses Google Analytics, which in turn uses cookies. Google Analytics allows us to see how many
|
||||
individual users of Compiler Explorer there are, how often users visit us, the average amount of time spent on the
|
||||
site, the frequency and distribution of compilers selected, and so on. It is invaluable in helping us make
|
||||
decisions in prioritising work on the site. It's important to note that these cookies are anonymous: we don't know
|
||||
who each individual user is. Our Google Analytics settings prevent data being retained for more than 14 months. The
|
||||
cookie stored is a first party cookie: you will find it in your browser under "godbolt.org" cookies.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Your privacy is important to us, and you may opt out of this tracking at any time using the buttons on this dialog,
|
||||
with no loss of access or functionality of Compiler Explorer.
|
||||
</p>
|
||||
|
||||
<h2><span style="color: darkslategray">Necessary</span> Local Storage</h2>
|
||||
<p>
|
||||
To store your preferred options between sessions, such as your input code and user interface layout, we make use of
|
||||
your browser's local storage, where we place:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>The current page state, such as:
|
||||
<ul>
|
||||
<li>Your current code</li>
|
||||
<li>Selected compilers and their options</li>
|
||||
<li>Pane layout</li>
|
||||
<li>Font sizes</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Your settings as shown in the settings popup (which can be found at: More > Settings), such as:
|
||||
<ul>
|
||||
<li>Your theme selection</li>
|
||||
<li>The default language</li>
|
||||
<li>Compile-as-you-type settings</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Note that the usage of local storage is necessary for the proper functioning of the site, and it won't be disabled
|
||||
if you choose to not grant cookie usage consent. This information is not used to track any user identifying
|
||||
information. The data stored locally is only that required by the site to function.
|
||||
</p>
|
||||
|
||||
<h3>How to control the cookies</h3>
|
||||
<p>
|
||||
You can change your cookie consent decision on Compiler Explorer by pressing one of the following buttons:
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
63
static/generated/cookies.pug
Normal file
63
static/generated/cookies.pug
Normal file
@@ -0,0 +1,63 @@
|
||||
// Be aware: modifying this file in any way will cause a pop-up to users telling them the cookie policy has changed.
|
||||
html(lang="en")
|
||||
body
|
||||
span(id="last-changed")
|
||||
| Last changed on:
|
||||
|
|
||||
time(id="changed-date" datetime=lastTime) #{lastTime}
|
||||
|
|
||||
| (
|
||||
i
|
||||
a(href="https://github.com/compiler-explorer/compiler-explorer/commit/#{lastCommit}" target="_blank") diff
|
||||
| )
|
||||
|
||||
h2 Compiler Explorer Cookie Policy
|
||||
|
||||
p
|
||||
| Browsers support the storing and sending back of small text files called "Cookies". These cookie files can be
|
||||
| used (amongst other things) to help track the usage of a website. See
|
||||
|
|
||||
a(href="https://developer.mozilla.org/docs/Web/HTTP/Cookies"
|
||||
target="_blank"
|
||||
rel="noreferrer noopener") the Mozilla description of cookies
|
||||
|
|
||||
| for more details.
|
||||
|
||||
p
|
||||
| Compiler Explorer uses Google Analytics, which in turn uses cookies. Google Analytics allows us to see how many
|
||||
| individual users there are, how often users visit us, the average amount of time spent on the
|
||||
| site, the frequency and distribution of compilers selected, and so on. It is invaluable in helping us make
|
||||
| decisions in prioritising work on the site. It's important to note that these cookies are anonymous: we don't know
|
||||
| who each individual user is. Our Google Analytics settings prevent data being retained for more than 14 months. The
|
||||
| cookie stored is a first party cookie: you will find it in your browser under "godbolt.org" cookies.
|
||||
|
||||
p
|
||||
| Your privacy is important to us, and you may opt out of this tracking at any time using the buttons on this dialog,
|
||||
| with no loss of access or functionality of Compiler Explorer.
|
||||
|
||||
h2 #[span(style="color: darkslategray") Necessary] Local Storage
|
||||
|
||||
p
|
||||
| To store your preferred options between sessions, such as your input code and user interface layout, we make use of
|
||||
| your browser's local storage, where we place:
|
||||
|
||||
ul
|
||||
li The current page state, such as:
|
||||
ul
|
||||
li Your current code
|
||||
li Selected compilers and their options
|
||||
li Pane layout
|
||||
li Font sizes
|
||||
li Your settings as shown in the settings popup (which can be found at: More > Settings), such as:
|
||||
ul
|
||||
li Your theme selection
|
||||
li The default language
|
||||
li Compile-as-you-type settings
|
||||
|
||||
p
|
||||
| Note that the usage of local storage is necessary for the proper functioning of the site, and it won't be disabled
|
||||
| if you choose to not grant cookie usage consent. This information is not used to track any user identifying
|
||||
| information. The data stored locally is only that required by the site to function.
|
||||
|
||||
h3 How to control the cookies
|
||||
p You can change your cookie consent decision on Compiler Explorer by pressing one of the following buttons:
|
||||
@@ -1,174 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<!--
|
||||
Be aware: modifying this file in any way will cause a pop-up to users telling them the privacy policy has changed.
|
||||
-->
|
||||
|
||||
<html lang="en">
|
||||
<body>
|
||||
|
||||
<!--
|
||||
No need to update this! It's done by the build process.
|
||||
-->
|
||||
<span id="last-changed">
|
||||
Last changed on: <time id="changed-date" datetime="{{lastTime}}">{{lastTime}}</time>
|
||||
<i>
|
||||
(<a href="https://github.com/compiler-explorer/compiler-explorer/commit/{{lastCommit}}" target="_blank">diff</a>)
|
||||
</i>
|
||||
</span>
|
||||
|
||||
<h2>Compiler Explorer Privacy Policy</h2>
|
||||
|
||||
<p>
|
||||
Thanks for your interest in what Compiler Explorer does with your data. Data protection is really
|
||||
important to the Compiler Explorer team, and we want to be very clear about what we do with your data.
|
||||
</p>
|
||||
|
||||
<h3>Who we are</h3>
|
||||
|
||||
<p>
|
||||
Compiler Explorer was created by and is primarily administrated by
|
||||
<a href="mailto:matt@godbolt.org">Matt Godbolt</a>,
|
||||
along with a number of volunteers (including, but not limited to those listed in our "<a
|
||||
href="https://github.com/compiler-explorer/compiler-explorer/blob/main/AUTHORS.md" target="_blank"
|
||||
rel="noreferrer noopener">Authors</a>" documentation).
|
||||
It is run on a best-effort basis, and is not a commercial product. We do our best
|
||||
to keep your data safe, but welcome help from the community: See our
|
||||
<a href="https://github.com/compiler-explorer/compiler-explorer" target="_blank"
|
||||
rel="noreferrer noopener">GitHub project page</a> if you wish to help.
|
||||
</p>
|
||||
|
||||
<h3>Your data</h3>
|
||||
|
||||
<p>
|
||||
In order to process compilation and execution requests, your browser sends the source code you typed in the editor
|
||||
window along with your chosen compiler and options to the Compiler Explorer servers. There, the source code is
|
||||
written to disk and your chosen compiler is invoked on it. If your request was to have your code executed, the
|
||||
resulting executable is run. The outputs from compilation and execution are processed and sent back to your web
|
||||
browser, where they're shown. Shortly after this process completes, your source code is deleted from disk. If, in
|
||||
processing your query, an issue with Compiler Explorer is found, your code may be kept for up to a week in order to
|
||||
help debug and diagnose the problem. Only the Compiler Explorer team will have access to your code, and only for the
|
||||
purposes of debugging the site: we will never share your code with anyone.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If you choose a Microsoft compiler, then your code may be sent to and compiled on a machine administrated by
|
||||
Microsoft. Such code is covered by the <a href="https://privacy.microsoft.com/en-US/" target="_blank">Microsoft
|
||||
Privacy Policy.</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The source code and options are also subject to a one-way hash, which is used to cache the results to speed up
|
||||
subsequent compilations of the same code. The cache is in-memory and on-disk. It's impossible to reconstruct the
|
||||
source code from the hash, but the resulting assembly code or binary output (the compilation result) is stored as
|
||||
plain text. There's no way to enumerate the in-memory cache contents. In exceptional cases, administrator members of
|
||||
the Compiler Explorer team may be able to enumerate the disk caches and retrieve the compilation output, but with no
|
||||
way to trace it back to the source code.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In short: your source code is stored in plaintext for the minimum time feasible to be able to process your request.
|
||||
After that, it is discarded and is inaccessible. In very rare cases your code may be kept for a little longer (at
|
||||
most a week) to help debug issues in Compiler Explorer.
|
||||
</p>
|
||||
|
||||
<h4>Short links</h4>
|
||||
|
||||
<p>
|
||||
If you choose to share your code using the "Share" dropdown, then the user interface state including the source code
|
||||
is stored. For a "Full" link, this information is encoded into the URL as a URL hash (e.g.
|
||||
<code>https://godbolt.org/#ui_state_and_code</code>). For short URLs, the interface state is stored on Compiler
|
||||
Explorer's servers, and a shortened name uniquely referring to this data is returned. The shortened name comes from
|
||||
a secure hash of the state, and without knowing the name it is infeasible to access the data. Only Compiler Explorer
|
||||
administrators can access this data directly. Obfuscated IP addresses and creation time are stored alongside this
|
||||
data, to enable spam detection. Links of this form look like <code>https://godbolt.org/z/SHORTNAME</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Prior to storing data itself, Compiler Explorer used an external URL shortening service
|
||||
(<a href="https://goo.gl/" target="_blank">goo.gl</a>) and the resulting short URL was rewritten as
|
||||
<code>https://godbolt.org/g/SHORTURLPART</code>. The storage for the user experience state in this case remains with
|
||||
the short URL provider, not Compiler Explorer.
|
||||
</p>
|
||||
|
||||
<h4>Application, web and error logs</h4>
|
||||
|
||||
<p>
|
||||
Compiler Explorer keeps application logs, which contain semi-anonymised IP addresses, but no other personally
|
||||
identifying information. When a long URL is clicked, the hash part of the URL is not sent to the server, so the user
|
||||
state (including the source code) is NOT exposed in the web log. If a user clicks a short URL, then the short form
|
||||
IS exposed in the web log (as <code>https://godbolt.org/g/SHORTURLPART</code>) and from this the source code can be
|
||||
retrieved. As such, if you create a short URL of your code, your source code and other user state can in principle
|
||||
be retrieved from the web log of Compiler Explorer.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Compiler Explorer uses Amazon's web serving, load balancing and edge caching systems. In order to debug and diagnose
|
||||
Compiler Explorer, to help track down and block Denial of Service attacks, and to gather statistics about Compiler
|
||||
Explorer's performance and usage, the logs from these systems are archived. These logs contain the full IP addresses
|
||||
of requests. They are kept for no more than one month, after which they are permanently deleted.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If your web browser experiences an error, we use a third party reporting system (<a
|
||||
href="https://sentry.io/">Sentry</a>). This keeps information, including your IP address and web browser user
|
||||
agent, for no more than 90 days.
|
||||
</p>
|
||||
|
||||
<h4>Executing your code</h4>
|
||||
|
||||
<p>
|
||||
For certain configurations, we may support executing the results of your compilation on the Compiler Explorer
|
||||
servers. Execution occurs in a heavily locked-down, isolated environment. We have made reasonable efforts to protect
|
||||
both the Compiler Explorer site and other concurrently-processed requests from information leakage due to rogue
|
||||
executions.
|
||||
</p>
|
||||
|
||||
<h4>Cookies</h4>
|
||||
|
||||
<p>
|
||||
Separately, Compiler Explorer uses small pieces of information stored on your computer: Cookies and Browser Local
|
||||
Storage. Cookies are only used with the user's permission, and are used with external analytics services (e.g.
|
||||
Google Analytics) to gather statistics on Compiler Explorer usage. This information is used to help the Compiler
|
||||
Explorer team plan for future updates and hardware upgrades in order to ensure the site remains stable and
|
||||
responsive. Local storage is used to remember the user's settings, source code and user interface configuration, so
|
||||
that it's available when the user visits the Compiler Explorer site again. This information is not transmitted to
|
||||
Compiler Explorer, except as described above in order to fulfil the user's requests. There is a
|
||||
<a href="#cookies" rel="noreferrer noopener">separate document</a> covering more on this. Statistics tracking
|
||||
information is kept for 14 months, after which it is removed.
|
||||
</p>
|
||||
|
||||
<h3>Your choices</h3>
|
||||
|
||||
<p>
|
||||
Compiler Explorer is an open source project. If you are concerned about any of the data protection measures outlined
|
||||
above, or about what happens to your source code, you are encouraged to run your own local instance of Compiler
|
||||
Explorer. Instructions on how to do this are on the
|
||||
<a href="https://github.com/compiler-explorer/compiler-explorer" target="_blank"
|
||||
rel="noreferrer noopener">GitHub project page</a>.
|
||||
</p>
|
||||
|
||||
<h3>Compiler Explorer and the GDPR</h3>
|
||||
|
||||
<p>
|
||||
The Compiler Explorer team believes the Compiler Explorer site is compliant with the EU's General Data Protection
|
||||
Regulation (GDPR). Specifically, we store no personally identifying information, we anonymise the little data that
|
||||
we do have and we do not permanently store any user data.
|
||||
</p>
|
||||
|
||||
<h4>Name and Address of the controller</h4>
|
||||
<p>
|
||||
The Controller for the purposes of the General Data Protection Regulation (GDPR), other data protection laws
|
||||
applicable in Member states of the European Union and other provisions related to data protection is:
|
||||
</p>
|
||||
|
||||
<div>
|
||||
Matt Godbolt<br>
|
||||
2626 Orrington Ave<br>
|
||||
Evanston IL 60201 USA<br>
|
||||
+1 312 792-7931<br>
|
||||
<a href="mailto:matt@godbolt.org">matt@godbolt.org</a>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
164
static/generated/privacy.pug
Normal file
164
static/generated/privacy.pug
Normal file
@@ -0,0 +1,164 @@
|
||||
//Be aware: modifying this file in any way will cause a pop-up to users telling them the privacy policy has changed.
|
||||
html(lang="en")
|
||||
body
|
||||
span(id="last-changed")
|
||||
| Last changed on:
|
||||
|
|
||||
time(id="changed-date" datetime=lastTime) #{lastTime}
|
||||
|
|
||||
| (
|
||||
i
|
||||
a(href="https://github.com/compiler-explorer/compiler-explorer/commit/#{lastCommit}" target="_blank") diff
|
||||
| )
|
||||
|
||||
h2 Compiler Explorer Privacy Policy
|
||||
|
||||
p
|
||||
| Thanks for your interest in what Compiler Explorer does with your data. Data protection is really
|
||||
| important to the Compiler Explorer team, and we want to be very clear about what we do with your data.
|
||||
|
||||
h3 Who we are
|
||||
|
||||
p
|
||||
| Compiler Explorer was created by and is primarily administrated by
|
||||
|
|
||||
a(href="mailto:matt@godbolt.org") Matt Godbolt
|
||||
| , along with a number of volunteers (including, but not limited to those listed in our "
|
||||
a(href="https://github.com/compiler-explorer/compiler-explorer/blob/main/AUTHORS.md"
|
||||
target="_blank" rel="noreferrer noopener") Authors
|
||||
| " documentation).
|
||||
| It is run on a best-effort basis, and is not a commercial product. We do our best
|
||||
| to keep your data safe, but welcome help from the community: See our
|
||||
|
|
||||
a(href="https://github.com/compiler-explorer/compiler-explorer"
|
||||
target="_blank" rel="noreferrer noopener") GitHub project page
|
||||
|
|
||||
| if you wish to help.
|
||||
|
||||
h3 Your data
|
||||
|
||||
p
|
||||
| In order to process compilation and execution requests, your browser sends the source code you typed in the editor
|
||||
| window along with your chosen compiler and options to the Compiler Explorer servers. There, the source code is
|
||||
| written to disk and your chosen compiler is invoked on it. If your request was to have your code executed, the
|
||||
| resulting executable is run. The outputs from compilation and execution are processed and sent back to your web
|
||||
| browser, where they're shown. Shortly after this process completes, your source code is deleted from disk. If, in
|
||||
| processing your query, an issue with Compiler Explorer is found, your code may be kept for up to a week in order to
|
||||
| help debug and diagnose the problem. Only the Compiler Explorer team will have access to your code, and only for the
|
||||
| purposes of debugging the site: we will never share your code with anyone.
|
||||
|
||||
p
|
||||
| If you choose a Microsoft compiler, then your code may be sent to and compiled on a machine administrated by
|
||||
| Microsoft. Such code is covered by the
|
||||
|
|
||||
a(href="https://privacy.microsoft.com/en-US/privacy.pug" target="_blank") Microsoft Privacy Policy.
|
||||
|
||||
p
|
||||
| The source code and options are also subject to a one-way hash, which is used to cache the results to speed up
|
||||
| subsequent compilations of the same code. The cache is in-memory and on-disk. It's impossible to reconstruct the
|
||||
| source code from the hash, but the resulting assembly code or binary output (the compilation result) is stored as
|
||||
| plain text. There's no way to enumerate the in-memory cache contents. In exceptional cases, administrator members of
|
||||
| the Compiler Explorer team may be able to enumerate the disk caches and retrieve the compilation output, but with no
|
||||
| way to trace it back to the source code.
|
||||
|
||||
p
|
||||
| In short: your source code is stored in plaintext for the minimum time feasible to be able to process your request.
|
||||
| After that, it is discarded and is inaccessible. In very rare cases your code may be kept for a little longer (at
|
||||
| most a week) to help debug issues in Compiler Explorer.
|
||||
|
||||
h4 Short links
|
||||
|
||||
p
|
||||
| If you choose to share your code using the "Share" dropdown, then the user interface state including the source code
|
||||
| is stored. For a "Full" link, this information is encoded into the URL as a URL hash (e.g.
|
||||
| #[code https://godbolt.org/#ui_state_and_code]). For short URLs, the interface state is stored on
|
||||
| Compiler Explorer's servers, and a shortened name uniquely
|
||||
| referring to this data is returned. The shortened name comes from a secure hash of the state, and without
|
||||
| knowing the name it is infeasible to access the data. Only Compiler Explorer administrators can access this data
|
||||
| directly. Obfuscated IP addresses and creation time are stored alongside this data, to enable spam detection.
|
||||
| Links of this form look like #[code https://godbolt.org/z/SHORTNAME].
|
||||
|
||||
p
|
||||
| Prior to storing data itself, Compiler Explorer used an external URL shortening service (
|
||||
a(href="https://goo.gl/" target="_blank") goo.gl
|
||||
| ) and the resulting short URL was rewritten as #[code https://godbolt.org/g/SHORTURLPART].
|
||||
| The storage for the user experience state in this case remains with the short URL provider,
|
||||
| not Compiler Explorer.
|
||||
|
||||
h4 Application, web and error logs
|
||||
|
||||
p
|
||||
| Compiler Explorer keeps application logs, which contain semi-anonymised IP addresses, but no other personally
|
||||
| identifying information. When a long URL is clicked, the hash part of the URL is not sent to the server, so the user
|
||||
| state (including the source code) is NOT exposed in the web log. If a user clicks a short URL, then the short form
|
||||
| #[em is] exposed in the web log (as #[code https://godbolt.org/g/SHORTURLPART]) and from this the source code can be
|
||||
| retrieved. As such, if you create a short URL of your code, your source
|
||||
| code and other user state can in principle be retrieved from the web log of Compiler Explorer.
|
||||
|
||||
p
|
||||
| Compiler Explorer uses Amazon's web serving, load balancing and edge caching systems. In order to debug and diagnose
|
||||
| Compiler Explorer, to help track down and block Denial of Service attacks, and to gather statistics about Compiler
|
||||
| Explorer's performance and usage, the logs from these systems are archived. These logs contain the full IP addresses
|
||||
| of requests. They are kept for no more than one month, after which they are permanently deleted.
|
||||
|
||||
p
|
||||
| If your web browser experiences an error, we use a third party reporting system (
|
||||
a(href="https://sentry.io/" target="_blank") Sentry
|
||||
| ). This keeps information, including your IP address and web browser user agent, for no more than 90 days.
|
||||
|
||||
h4 Executing your code
|
||||
|
||||
p
|
||||
| For certain configurations, we may support executing the results of your compilation on the Compiler Explorer
|
||||
| servers. Execution occurs in a heavily locked-down, isolated environment. We have made reasonable efforts to protect
|
||||
| both the Compiler Explorer site and other concurrently-processed requests from information leakage due to rogue
|
||||
| executions.
|
||||
|
||||
h4 Cookies
|
||||
|
||||
p
|
||||
| Separately, Compiler Explorer uses small pieces of information stored on your computer: Cookies and Browser Local
|
||||
| Storage. Cookies are only used with the user's permission, and are used with external analytics services (e.g.
|
||||
| Google Analytics) to gather statistics on Compiler Explorer usage. This information is used to help the Compiler
|
||||
| Explorer team plan for future updates and hardware upgrades in order to ensure the site remains stable and
|
||||
| responsive. Local storage is used to remember the user's settings, source code and user interface configuration, so
|
||||
| that it's available when the user visits the Compiler Explorer site again. This information is not transmitted to
|
||||
| Compiler Explorer, except as described above in order to fulfil the user's requests. There is a
|
||||
|
|
||||
a(href="#cookies" rel="noreferrer noopener") separate document
|
||||
|
|
||||
| covering more on this. Statistics tracking information is kept for 14 months, after which it is removed.
|
||||
|
||||
h3 Your choices
|
||||
|
||||
p
|
||||
| Compiler Explorer is an open source project. If you are concerned about any of the data protection measures outlined
|
||||
| above, or about what happens to your source code, you are encouraged to run your own local instance of Compiler
|
||||
| Explorer. Instructions on how to do this are on the
|
||||
|
|
||||
a(href="https://github.com/compiler-explorer/compiler-explorer"
|
||||
target="_blank" rel="noreferrer noopener") GitHub project page
|
||||
| .
|
||||
|
||||
h3 Compiler Explorer and the GDPR
|
||||
|
||||
p
|
||||
| The Compiler Explorer team believes the Compiler Explorer site is compliant with the EU's General Data Protection
|
||||
| Regulation (GDPR). Specifically, we store no personally identifying information, we anonymise the little data that
|
||||
| we do have and we do not permanently store any user data.
|
||||
|
||||
h4 Name and Address of the controller
|
||||
|
||||
p
|
||||
| The Controller for the purposes of the General Data Protection Regulation (GDPR), other data protection laws
|
||||
| applicable in Member states of the European Union and other provisions related to data protection is:
|
||||
|
||||
div
|
||||
| Matt Godbolt
|
||||
br
|
||||
| 2626 Orrington Ave
|
||||
br
|
||||
| Evanston IL 60201 USA
|
||||
br
|
||||
| +1 312 792-7931<br>
|
||||
a(href="mailto:matt@godbolt.org") matt@godbolt.org
|
||||
@@ -69,6 +69,11 @@ var hasUIBeenReset = false;
|
||||
var simpleCooks = new SimpleCook();
|
||||
var historyWidget = new HistoryWidget();
|
||||
|
||||
var policyDocuments = {
|
||||
cookies: require('./generated/cookies.pug').default,
|
||||
privacy: require('./generated/privacy.pug').default,
|
||||
};
|
||||
|
||||
function setupSettings(hub) {
|
||||
var eventHub = hub.layout.eventHub;
|
||||
var defaultSettings = {
|
||||
@@ -111,7 +116,7 @@ function setupSettings(hub) {
|
||||
}
|
||||
|
||||
function hasCookieConsented(options) {
|
||||
return jsCookie.get(options.policies.cookies.key) === options.policies.cookies.hash;
|
||||
return jsCookie.get(options.policies.cookies.key) === policyDocuments.cookies.hash;
|
||||
}
|
||||
|
||||
function isMobileViewer() {
|
||||
@@ -130,17 +135,18 @@ function setupButtons(options) {
|
||||
// so we instead trigger a click here when we want it to open with this effect. Sorry!
|
||||
if (options.policies.privacy.enabled) {
|
||||
$('#privacy').on('click', function (event, data) {
|
||||
$.get(window.location.origin + window.httpRoot + 'static/generated/privacy.html').done(function (policy) {
|
||||
var modal = alertSystem.alert(data && data.title ? data.title : 'Privacy policy', policy);
|
||||
calcLocaleChangedDate(modal);
|
||||
// I can't remember why this check is here as it seems superfluous
|
||||
if (options.policies.privacy.enabled) {
|
||||
jsCookie.set(options.policies.privacy.key, options.policies.privacy.hash, {
|
||||
expires: 365,
|
||||
sameSite: 'strict',
|
||||
});
|
||||
}
|
||||
});
|
||||
var modal = alertSystem.alert(
|
||||
data && data.title ? data.title : 'Privacy policy',
|
||||
policyDocuments.privacy.text
|
||||
);
|
||||
calcLocaleChangedDate(modal);
|
||||
// I can't remember why this check is here as it seems superfluous
|
||||
if (options.policies.privacy.enabled) {
|
||||
jsCookie.set(options.policies.privacy.key, policyDocuments.privacy.hash, {
|
||||
expires: 365,
|
||||
sameSite: 'strict',
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -155,19 +161,17 @@ function setupButtons(options) {
|
||||
);
|
||||
};
|
||||
$('#cookies').on('click', function () {
|
||||
$.get(window.location.origin + window.httpRoot + 'static/generated/cookies.html').done(function (cookies) {
|
||||
var modal = alertSystem.ask(getCookieTitle(), cookies, {
|
||||
yes: function () {
|
||||
simpleCooks.callDoConsent.apply(simpleCooks);
|
||||
},
|
||||
yesHtml: 'Consent',
|
||||
no: function () {
|
||||
simpleCooks.callDontConsent.apply(simpleCooks);
|
||||
},
|
||||
noHtml: 'Do NOT consent',
|
||||
});
|
||||
calcLocaleChangedDate(modal);
|
||||
var modal = alertSystem.ask(getCookieTitle(), policyDocuments.cookies.text, {
|
||||
yes: function () {
|
||||
simpleCooks.callDoConsent.apply(simpleCooks);
|
||||
},
|
||||
yesHtml: 'Consent',
|
||||
no: function () {
|
||||
simpleCooks.callDontConsent.apply(simpleCooks);
|
||||
},
|
||||
noHtml: 'Do NOT consent',
|
||||
});
|
||||
calcLocaleChangedDate(modal);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -183,9 +187,7 @@ function setupButtons(options) {
|
||||
});
|
||||
|
||||
$('#changes').on('click', function () {
|
||||
$.get(window.location.origin + window.httpRoot + 'static/generated/changelog.html').done(function (changelog) {
|
||||
alertSystem.alert('Changelog', $(changelog));
|
||||
});
|
||||
alertSystem.alert('Changelog', $(require('./generated/changelog.pug').default.text));
|
||||
});
|
||||
|
||||
$('#ces').on('click', function () {
|
||||
@@ -338,7 +340,7 @@ function initPolicies(options) {
|
||||
$('#privacy').trigger('click', {
|
||||
title: 'New Privacy Policy. Please take a moment to read it',
|
||||
});
|
||||
} else if (options.policies.privacy.hash !== jsCookie.get(options.policies.privacy.key)) {
|
||||
} else if (policyDocuments.privacy.hash !== jsCookie.get(options.policies.privacy.key)) {
|
||||
// When the user has already accepted the privacy, just show a pretty notification.
|
||||
var ppolicyBellNotification = $('#policyBellNotification');
|
||||
var pprivacyBellNotification = $('#privacyBellNotification');
|
||||
@@ -355,7 +357,7 @@ function initPolicies(options) {
|
||||
}
|
||||
}
|
||||
simpleCooks.setOnDoConsent(function () {
|
||||
jsCookie.set(options.policies.cookies.key, options.policies.cookies.hash, {
|
||||
jsCookie.set(options.policies.cookies.key, policyDocuments.cookies.hash, {
|
||||
expires: 365,
|
||||
sameSite: 'strict',
|
||||
});
|
||||
@@ -381,7 +383,7 @@ function initPolicies(options) {
|
||||
// '' means no consent. Hash match means consent of old. Null means new user!
|
||||
var storedCookieConsent = jsCookie.get(options.policies.cookies.key);
|
||||
if (options.policies.cookies.enabled) {
|
||||
if (storedCookieConsent !== '' && options.policies.cookies.hash !== storedCookieConsent) {
|
||||
if (storedCookieConsent !== '' && policyDocuments.cookies.hash !== storedCookieConsent) {
|
||||
simpleCooks.show();
|
||||
var cpolicyBellNotification = $('#policyBellNotification');
|
||||
var cprivacyBellNotification = $('#privacyBellNotification');
|
||||
|
||||
@@ -22,14 +22,12 @@
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import {execSync} from 'child_process';
|
||||
import path from 'path';
|
||||
import {fileURLToPath} from 'url';
|
||||
|
||||
/* eslint-disable node/no-unpublished-import */
|
||||
import CopyWebpackPlugin from 'copy-webpack-plugin';
|
||||
import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
|
||||
import Handlebars from 'handlebars';
|
||||
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
|
||||
import MonacoEditorWebpackPlugin from 'monaco-editor-webpack-plugin';
|
||||
import TerserPlugin from 'terser-webpack-plugin';
|
||||
@@ -43,20 +41,6 @@ console.log(`webpack config for ${isDev ? 'development' : 'production'}.`);
|
||||
const distPath = path.resolve(__dirname, 'out', 'dist');
|
||||
const staticPath = path.resolve(__dirname, 'out', 'webpack', 'static');
|
||||
|
||||
function execGit(command) {
|
||||
const gitResult = execSync(command);
|
||||
if (!gitResult) {
|
||||
throw new Error(`Failed to execute ${command}`);
|
||||
}
|
||||
return gitResult.toString();
|
||||
}
|
||||
|
||||
const gitChanges = execGit('git log --date=local --after="3 months ago" "--grep=(#[0-9]*)" --oneline')
|
||||
.split('\n')
|
||||
.map(line => line.match(/(?<hash>\w+) (?<description>.*)/))
|
||||
.filter(x => x)
|
||||
.map(match => match.groups);
|
||||
|
||||
// Hack alert: due to a variety of issues, sometimes we need to change
|
||||
// the name here. Mostly it's things like webpack changes that affect
|
||||
// how minification is done, even though that's supposed not to matter.
|
||||
@@ -98,19 +82,7 @@ const plugins = [
|
||||
'window.PRODUCTION': JSON.stringify(!isDev),
|
||||
}),
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{from: './static/favicon.ico', to: path.resolve(distPath, 'static', 'favicon.ico')},
|
||||
{
|
||||
from: './static/generated/*.html',
|
||||
to: path.resolve(distPath),
|
||||
toType: 'dir',
|
||||
transform: (content, filename) => {
|
||||
const lastTime = execGit(`git log -1 --format=%cd "${filename}"`).trimEnd();
|
||||
const lastCommit = execGit(`git log -1 --format=%h "${filename}"`).trimEnd();
|
||||
return Handlebars.compile(content.toString())({gitChanges, lastTime, lastCommit});
|
||||
},
|
||||
},
|
||||
],
|
||||
patterns: [{from: './static/favicon.ico', to: path.resolve(distPath, 'static', 'favicon.ico')}],
|
||||
}),
|
||||
];
|
||||
|
||||
@@ -186,8 +158,8 @@ export default {
|
||||
parser: {dataUrlCondition: {maxSize: 8192}},
|
||||
},
|
||||
{
|
||||
test: /\.(html)$/,
|
||||
loader: 'html-loader',
|
||||
test: /.pug$/,
|
||||
loader: './etc/scripts/parsed_pug_file.js',
|
||||
},
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
|
||||
Reference in New Issue
Block a user