Skip to content

Commit

Permalink
chore(*): updating terms, contact info, and README (#83)
Browse files Browse the repository at this point in the history
chore(*): update terms, contact info, and README
  • Loading branch information
tbash authored Feb 21, 2019
1 parent 11fee03 commit 5179882
Show file tree
Hide file tree
Showing 9 changed files with 685 additions and 80 deletions.
2 changes: 1 addition & 1 deletion CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at ellie@lukewestby.com. All
reported by contacting the project team at ellie@tba.sh. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Expand Down
43 changes: 27 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,38 @@

## Development

Ellie is a web application with an Elixir backend and an Elm frontend. It runs inside Docker.
For development we use docker-compose to install all of the software and start up the
various programs in the correct order. To begin developing Ellie, all you need to do is:
Ellie is a web application with an Elixir backend and an Elm frontend.
For development we rely on the Mix and Phoenix development cylce tasks.
The development environment requires:

1. Install Docker
- [Elixir](https://elixir-lang.org/install.html) 1.7
- [PostgreSQL](https://www.postgresql.org/) 10
- [Node](https://nodejs.org) LTS

[Official installation instructions](https://docs.docker.com/install/)
Provided the local postgres server is running and `createuser -s postgres` has been run, to setup and then start the dev
server, run the following:

2. Start with docker-compose

```
$ docker-compose up
```sh
$ make bootstrap
$ make serve
```

The first time you run this it will download the images for our base operating system, install
all of the software for building and running, and compile everything. It attaches the project
directory as a volume, so all of the build artifacts will be written to your file system.
## Production

If you are using Docker for Mac you may need to make adjustments to your file sharing permissions
under Preferences > File Sharing.
To build the AWS infrastructure that Ellie can be deployed to, run the folling:

> **⚠️ WARNING**
> It's important to be careful about editor tools that modify these build artifacts! They are
> generated on a Linux operating system and might be incompatible with your machine.
> This does not operate in the Free Tier, running the following script will incur a cost from AWS.
```sh
$ GITHUB_TOKEN=<github token> SSH_KEY_NAME=<ssh key name> scripts/cfn create
```

After this is done, you will need to manually setup the public listener(s) on the load balancer and ensure the webhook
has been correctly configured. The pipeline will now kick off after a new release has been tagged.

The following script can be used to tear down the AWS infrastructure:

```sh
$ GITHUB_TOKEN=<github token> SSH_KEY_NAME=<ssh key name> scripts/cfn destroy
```
121 changes: 63 additions & 58 deletions assets/src/Pages/Editor/Main.js
Original file line number Diff line number Diff line change
@@ -1,74 +1,79 @@
export default {
flags(current) {
const recovery = localStorage.getItem('Pages.Editor.recovery')
const user = localStorage.getItem('Pages.Editor.user')
const recovery = localStorage.getItem("Pages.Editor.recovery");
const user = localStorage.getItem("Pages.Editor.user");
return Object.assign({}, current, {
recovery: recovery ? JSON.parse(recovery) : null,
user: user ? JSON.parse(user) : null,
latestTerms: window.ellieConfig.latestTerms
})
});
},
start(app) {
window.addEventListener('online', () => app.ports.inbound.send(['NetworkStatus', true]))
window.addEventListener('offline', () => app.ports.inbound.send(['NetworkStatus', false]))
window.addEventListener("online", () =>
app.ports.inbound.send(["NetworkStatus", true])
);
window.addEventListener("offline", () =>
app.ports.inbound.send(["NetworkStatus", false])
);

let acknowledgedReload = false
const preventNavigation = (e) => {
e.returnValue = 'You have unsaved work. Are you sure you want to go?'
acknowledgedReload = true
}
let acknowledgedReload = false;
const preventNavigation = e => {
e.returnValue = "You have unsaved work. Are you sure you want to go?";
acknowledgedReload = true;
};

window.addEventListener("unload", () => {
if (acknowledgedReload) localStorage.removeItem("Pages.Editor.recovery");
});

window.addEventListener('unload', () => {
if (acknowledgedReload) localStorage.removeItem('Pages.Editor.recovery')
})

app.ports.outbound.subscribe(([tag, contents]) => {
switch (tag) {
case 'OpenInNewTab':
const [url] = contents
window.open(url, '_blank')
break

case 'UpdateUser':
const [user] = contents
localStorage.setItem('Pages.Editor.user', JSON.stringify(user))
break

case 'UpdateRecoveryRevision':
const [data] = contents
localStorage.setItem('Pages.Editor.recovery', JSON.stringify(data))
if (data !== null) window.addEventListener('beforeunload', preventNavigation)
else window.removeEventListener('beforeunload', preventNavigation)
break

case 'DownloadZip':
const [project, elm, html] = contents
import('jszip').then(JSZip => {
const zip = new JSZip()
zip.file('Main.elm', elm)
zip.file('index.html', html)
zip.file('elm.json', project)
zip.generateAsync({ type: 'blob' }).then(blob => {
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'ellie.zip'
a.click()
URL.revokeObjectURL(url)
})
})
break
case "OpenInNewTab":
const [url] = contents;
window.open(url, "_blank");
break;

case "UpdateUser":
const [user] = contents;
localStorage.setItem("Pages.Editor.user", JSON.stringify(user));
break;

case "UpdateRecoveryRevision":
const [data] = contents;
localStorage.setItem("Pages.Editor.recovery", JSON.stringify(data));
if (data !== null)
window.addEventListener("beforeunload", preventNavigation);
else window.removeEventListener("beforeunload", preventNavigation);
break;

case "DownloadZip":
const [project, elm, html] = contents;
import("jszip").then(({ default: JSZip }) => {
const zip = new JSZip();
zip.file("Main.elm", elm);
zip.file("index.html", html);
zip.file("elm.json", project);
zip.generateAsync({ type: "blob" }).then(blob => {
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "ellie.zip";
a.click();
URL.revokeObjectURL(url);
});
});
break;

case "MoveElmCursor":
const editor = document.getElementById("elm");
if (!editor) break;
const [line, column] = contents;
editor.moveCursor(line, column);
break;

case 'MoveElmCursor':
const editor = document.getElementById('elm')
if (!editor) break
const [line, column] = contents
editor.moveCursor(line, column)
break

default:
break
break;
}
})
});
}
}
};
4 changes: 2 additions & 2 deletions assets/src/Pages/Editor/Views/Setup.elm
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ terms state =
, Html.text "Report abuse or request removal of personal information at "
, Html.styled Html.a
[ color Theme.accent ]
[ Attributes.href <| "mailto:ellie@lukewestby.com" ]
[ Html.text "ellie@lukewestby.com" ]
[ Attributes.href <| "mailto:ellie@tba.sh" ]
[ Html.text "ellie@tba.sh" ]
, Html.text ". See our "
, Html.styled Html.a
[ color Theme.accent ]
Expand Down
4 changes: 2 additions & 2 deletions assets/src/Pages/Editor/Views/StatusBar.elm
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ view config =
, textDecoration none
, fontSize (px 16)
]
[ Attributes.href "/a/terms/3#privacy"
[ Attributes.href "/a/terms/4#privacy"
, Attributes.target "_self"
]
[ Html.text "Privacy" ]
Expand All @@ -51,7 +51,7 @@ view config =
, textDecoration none
, fontSize (px 16)
]
[ Attributes.href "/a/terms/3#terms"
[ Attributes.href "/a/terms/4#terms"
, Attributes.target "_self"
]
[ Html.text "Terms" ]
Expand Down
2 changes: 1 addition & 1 deletion lib/ellie_web/templates/page/config.html.eex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script>
window.ellieConfig = {
latestTerms: 3
latestTerms: 4
}
</script>
73 changes: 73 additions & 0 deletions lib/ellie_web/templates/page/terms/v4/index.html.eex
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
#whatsnew:target { display: block; }
#whatsnew:not(:target) { display: none; }
#terms:target { display: block; }
#terms:not(:target) { display: none; }
#privacy:target { display: block; }
#privacy:not(:target) { display: none; }
.tab {
font-size: 18px;
margin: 16px;
}
nav {
display: flex;
justify-content: center;
align-items: center;
}
a {
color: #FC6ECC;
}
html {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
color: #252525;
background-color: #DDDDDD;
padding: 16px;
}
</style>
</head>
<body>
<nav>
<a class="tab" href="#whatsnew">What's New?</a>
<a class="tab" href="#terms">Terms</a>
<a class="tab" href="#privacy">Privacy</a>
</nav>
<main>
<div id="whatsnew">
Ellie is now running on Amazon Web Services (AWS). A new cookie is introduced with the name
<strong>AWSALB</strong>, this encrypts information to direct traffic for maintaining sticky
sessions. Any previously stored cookies are no longer in use. The cookie is only used for the
purpose of maintaining expected behavior for subsequent requests and is refreshed with every
response. You can read more about this cookie in our <a href="#privacy">Privacy Notice</a>.
</div>
<div id="terms">
<%= render("terms/v4/terms_content.html") %>
</div>
<div id="privacy">
<%= render("terms/v4/privacy_content.html") %>
</div>
</main>
<script>
document
.querySelectorAll("a[href^='#']")
.forEach(function (link, i) {
link.addEventListener("click", function (event) {
event.preventDefault()
history.pushState({}, "", link.href)
history.pushState({}, "", link.href)
history.back()
})
if (i === 0 && window.location.hash === '') link.click()
})
</script>
</body>
</html>
78 changes: 78 additions & 0 deletions lib/ellie_web/templates/page/terms/v4/privacy_content.html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Privacy Policy

Last updated: February 15, 2019

Ellie is fully capable of respecting your data privacy while providing its service. Ellie does not intentionally collect _any_ personal data from you. Even so, we still want you to feel confident in our ability to respect your privacy, so this document outlines who we are, what data we do collect, and how it is used.

## Ellie's creators and operators

Ellie was created by Luke Westby and is now the owned and maintained by Brandon Ashley. Brandon operates Ellie from the state of Florida in the United States. Brandon can be reached for inquiries regarding ellie at the email address [email protected]. Ellie is open source and supported by the Elm language community. The source code for Ellie is located at https://github.com/ellie-app/ellie.

## Data Ellie collects

Ellie does not collect any personal data.

When interacting with Ellie you may submit the following information for storage on our servers:

- Code written in the Elm programming language
- Code written in the HTML, JavaScript, and CSS programming languages
- A short description of the code
- A selection of publicly accessible packages from http://package.elm-lang.org

Ellie is not a complicated service, and we do not need to collect more than this to provide that service. In order to protect your privacy you should not submit personal information in any of these fields. Every submission to Ellie is publicly accessible by design!

In addition to the information you may submit to our servers, the following information is stored in your browser:

- Visual settings, like font size and font family
- A local backup of the code you write, in order to recover from crashes

This data is stored directly in your browser and never sent to our servers or any third party service. It contains no directly identifying information and can be cleared as easily as deleting your browsing history.

Lastly, when an error occurs in our software we log that information with a third party service, [Sentry](https://sentry.io). These logs do not contain IP addresses, but may contain information about what browser you are using in addition to the code, description, and packages that you submitted. This information is permanently deleted after 6 days in Sentry's servers.

## User-generated content and third party links

Ellie's purpose is to share and serve user-submitted executable code. We cannot possibly review all code shared with Ellie, so be advised that code shared with Ellie may be malicious or contain abusive and inappropriate content. If you discover an Example shared with Ellie that does contain malicious content you can report it to [email protected] and we will act to correct the situation as quickly as possible. Our terms of service explicitly forbid the use of Ellie for malicious or illegal purposes, and we take these requests very seriously.

**Never submit passwords or personal information to a form shared on Ellie!**

In addition to user content, Ellie may also include links to third party websites in its user interface. These links are not subject to Ellie's privacy policy and are there for your convenience in discovering information related to Ellie, like source code and community discussions. These include, but are not limited to, https://github.com, https://slack.com, http://aws.amazon.com, and https://youtube.com.

## Usage of Ellie by minors

Ellie is not intended for use and may not be used by children under the age of 13. Children under the age of 18 must use Ellie with the permission and supervision of a parent or legal guardian. Ellie has no way of enforcing permission for children under the age of 18, and does not intend to collect any information from children just as it does not intend to collect personal information from anyone. If you discover that your child's information has been shared on Ellie please contact us at [email protected] or using the form at https://ellie.gdprform.io/ and we will ensure your child's information is removed.

## Sharing data with third parties

Just as we don't store any personal data for our own use, we will never collect and sell your personal data to another party! We do use the services of the following external data processors, although, once again, we do not collect or store personal data, including IP addresses

- [Amazon Web Services](https://aws.amazon.com) (application hosting, DNS, caching, and security)
- [Google Cloud Platform](https://cloud.google.com) (data storage)
- [Sentry](https://sentry.io) (error reporting)

Each of these third party data processors must only process your personal data in compliance with our privacy policy. These data processors also must sufficiently safeguard data we send to them. All of these external data processors are based in the United States. Google Cloud Platform, Sentry, and Amazon Web Services are certified compliant with EU-US Privacy Shield. Our database is located in the state of Oregon, USA. Our web server is in the state of N. Virginia, USA.

All data shared with Ellie is public and can be made available to law enforcement. Ellie does not collect access logs, so all the data we might be compelled to share is spelled out in the section "Data Ellie collects".

## Cookies and other tracking technologies

Ellie does not _directly_ use cookies, track users, or perform any form of advertising or retargeting for third parties. Previous versions of Ellie _did_ use cookies, though. While we have configured the server to attempt to delete them it is not always possible to succeed in doing so. You can use your browser's settings to delete any cookies Ellie may have stored prior to issuing this Privacy Policy and they will not be reintroduced.

Ellie makes use of one third party cookie to provide its service:

- **Provider**: Amazon Web Services
- **Purpose**: To identify your session and route to the same target when accessing Ellie. Read more at [https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html#sticky-sessions](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html#sticky-sessions)
- **Name**: `AWSALB`
- **Lifetime**: Between 1 second and 7 days.

## Changes to this policy

We may change this privacy policy. Whenever a new user comes to Ellie they are prompted to accept our terms of service and privacy policy before using the service. If you have already accepted this policy, you will be prompted to accept it again when it changes. We will also always include a summary of what has changed in the new version of the terms of service and privacy policy going forward.

## Requests regarding data on Ellie

Once again, Ellie does not intentionally collect any personal data from you. Even so, all data on Ellie is public. You may request us to send you a summary of any data you feel is relevant to you as a user. If you find that you have shared personal data on Ellie, inadvertently or otherwise, you have a right to request that it be removed. You may also request the removal of data that appears to be abusive, innapropriate, or illegal.

Ellie routinely downloads package information from the public Elm package registry at http://package.elm-lang.org. If you are pursuing the removal of personal information related to the contents of a package from the registry we will gladly assist you by purging your information from any caches of package information.

You may contact Ellie with a data request at [email protected] or using the form at https://ellie.gdprform.io/.
Loading

0 comments on commit 5179882

Please sign in to comment.