Skip to content

Commit

Permalink
Merge pull request #264 from HackGT/ground-truth
Browse files Browse the repository at this point in the history
Use Ground Truth for authentication
  • Loading branch information
petschekr committed Jun 25, 2019
2 parents 2e830a3 + b451c6b commit 5aacf38
Show file tree
Hide file tree
Showing 28 changed files with 563 additions and 1,833 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:10-alpine
FROM node:12-alpine
MAINTAINER Ryan Petschek <petschekr@gmail.com>

# Deis wants bash
Expand Down
66 changes: 16 additions & 50 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@
## Features

- Seamless OAuth and local signup logins with automatic email verification
- Get users up and running quickly with GitHub, Google, and Facebook OAuth logins right out of the box ([MyMLH](https://my.mlh.io) login planned)
- Full support for local logins as well if users choose
- Seamless OAuth and local signup logins with automatic email verification via [HackGT Ground Truth](https://github.com/HackGT/ground-truth)
- Get users up and running quickly with GitHub, Google, and Facebook OAuth or Georgia Tech CAS logins right out of the box
- Full support for local logins as well if users prefer
- Users can easily register (and confirm their attendance if accepted) and choose which "branch" they want to complete (e.g. partipant, mentor, volunteer) all from a single location
- Users can create or join a team any time before or after completing registration. Admins can configure the maximum team size (defaults to 4).
- For admins, the admin panel contains options for managing all aspects of registration including:
- Statistics about the user of sign ups, registrations, acceptances, and confirmations
- Graphs displaying aggregated registration data
- List of all users in a table including name, email, email verified status, admin status, and application status, and log in method
- List of all users in a table including name, email, admin status, and application status, and log in method
- List of all applicants with application responses and accept / unaccept button sortable by application branch and accepted status
- Acceptance emails are sent out only when a send acceptance emails button is clicked allowing for decisions to be reviewed before being finalized
- Setting application and confirmation open and close times as well as what question branches from `questions.json` are for applications, confirmations, or hidden
Expand Down Expand Up @@ -60,73 +60,39 @@ A [Dockerfile](Dockerfile) is provided for convenience.

Configuration should normally be done by editing the `server/config/config.json` file. Environment variables take precedence over `config.json` and should be used when those options need to be overridden or `config.json` can't be used for some reason (e.g. certain deployment scenarios).

### OAuth IDs and secrets

Can be obtained from:
- [GitHub](https://github.com/settings/developers)
- Register a new application
- Application name, URL, and description are up to you
- Callback URL should be in the format: `https://YOUR_DOMAIN/auth/github/callback`
- Local testing callback URL should be `http://localhost:3000/auth/github/callback`
- GitHub only lets you register one callback URL per application so you might want to make a testing application and a separate application for production usage.
- [Google API Console](https://console.developers.google.com/apis/credentials)
- Create an application
- Go to the credentials tab in the left panel
- Click Create credentials > OAuth client ID
- Set web application as the application type
- Give it a name (won't be shown publically, e.g. `HackGT Registration server testing`)
- Leave Authorized JavaScript origins blank
- List all testing / production callback URLs in Authorized redirect URIs
- Should be in the format: `https://YOUR_DOMAIN/auth/google/callback`
- For local testing: `http://localhost:3000/auth/google/callback`
- It is recommended that you create two OAuth applications with different IDs and secrets for testing and production usage.
- [Facebook](https://developers.facebook.com/)
- Create an application
- Add the Facebook Login product from the left panel
- Enable Client OAuth Login, Web OAuth Login, and Embedded Browser OAuth Login
- List all testing / production callback URLs in Valid OAuth redirect URLs
- Should be in the format: `https://YOUR_DOMAIN/auth/facebook/callback`
- For local testing: `http://localhost:3000/auth/facebook/callback`
- Optionally, repeat the process for separate testing and production applications

Environment Variable | Description
---------------------|------------
PRODUCTION | Set to `true` to set OAuth callbacks to production URLs (default: `false`)
PRODUCTION | Set to `true` to enable reverse proxy trusting (default: `false`)
PORT | The port the check in system should run on (default: `3000`)
MONGO_URL | The URL to the MongoDB server (default: `mongodb://localhost/`)
UNIQUE_APP_ID | The MongoDB database name to store data in (default: `registration`)
MONGO_URL | The URL to the MongoDB server (default: `mongodb://localhost/registration`)
VERSION_HASH | The Git short hash used to identify the current commit (default: parsed automatically from the `.git` folder, if it exists)
*SOURCE_VERSION* | Same as `VERSION_HASH` but overrides it if present. Used by Deis.
*WORKFLOW_RELEASE_CREATED_AT* | Provided by Deis (default: `null`)
*WORKFLOW_RELEASE_SUMMARY* | Provided by Deis (default: `null`)
ADMIN_KEY_SECRET | An API key used to authenticate as admin an access the GraphQL api (default: random key that changes every server restart)
COOKIE_MAX_AGE | The `maxAge` of cookies set in milliseconds (default: 6 months) **NOTE: this is different from the session TTL**
COOKIE_SECURE_ONLY | Whether session cookies should sent exclusively over secure connections (default: `false`)
PASSWORD_RESET_EXPIRATION | The time that password reset links sent via email should be valid for in milliseconds (default: 1 hour)
SESSION_SECRET | The secret used to sign and validate session cookies (default: random 32 bytes regenerated on every start up)
GITHUB_CLIENT_ID | OAuth client ID for GitHub *required*
GITHUB_CLIENT_SECRET | OAuth client secret for GitHub *required*
GOOGLE_CLIENT_ID | OAuth client ID for Google *required*
GOOGLE_CLIENT_SECRET | OAuth client secret for Google *required*
FACEBOOK_CLIENT_ID | OAuth client ID for Facebook *required*
FACEBOOK_CLIENT_SECRET | OAuth client secret for Facebook *required*
GROUND_TRUTH_URL | Base URL of [Ground Truth](https://github.com/HackGT/ground-truth) instance (e.g. `https://login.hack.gt`) *required*
GROUND_TRUTH_ID | OAuth client ID from Ground Truth *required*
GROUND_TRUTH_SECRET | OAuth client secret from Ground Truth *required*
EMAIL_FROM | The `From` header for sent emails (default: `HackGT Team <hello@hackgt.com>`)
EMAIL_KEY | The SendGrid API key for sending emails (default: *none*)
EMAIL_KEY | The SendGrid API key for sending emails (default: *none*) *required*
ADMIN_EMAILS | A JSON array of the emails of the users that you want promoted to admin status when they create their account (default: none)
EVENT_NAME | The current event's name which affects rendered templates and sent emails (default: `Untitled Event`)
STORAGE_ENGINE | The name of the storage engine that handles file uploads as defined in [storage.ts](server/storage.ts) (default: `disk`)
STORAGE_ENGINE_OPTIONS | JSON-encoded object containing options to be passed to the storage engine. Must at least contain a value for the `uploadDirectory` key. For the default `disk` storage engine, this directory is relative to the app's root, can be absolute, and will be created if it doesn't exist. (default: `{ "uploadDirectory": "uploads" }`)
DEFAULT_TIMEZONE | Timezone used for dates and times (default: `America/New_York`)
MAX_TEAM_SIZE | The maximum number of users allowed per team (default: `4`)
QUESTIONS_FILE | Specify a path for the `questions.json` file.
QUESTIONS_FILE | Specify a path for the `questions.json` file. (default: ./server/config/questions.json)
THEME_FILE | Specify a path for the `theme.css` file, which will be loaded last at every page.
FAVICON_FILE | Path to the favicon file (default is no favicon).
FAVICON_FILE_BASE64 | Same as `FAVICON_FILE_BASE64` but the file is base64 encoded.


## Contributing

If you happen to find a bug or have a feature you'd like to see implemented, please [file an issue](https://github.com/HackGT/registration/issues).
If you happen to find a bug or have a feature you'd like to see implemented, please [file an issue](https://github.com/HackGT/registration/issues).

If you have some time and want to help us out with development, thank you! You can get started by taking a look at the open issues, particularly the ones marked [help wanted](https://github.com/HackGT/registration/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) or [help wanted - beginner](https://github.com/HackGT/registration/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted+-+beginner%22). Feel free to ask questions to clarify things, determine the best way to implement a new feature or bug fix, or anything else!
If you have some time and want to help us out with development, thank you! You can get started by taking a look at the open issues, particularly the ones marked [help wanted](https://github.com/HackGT/registration/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) or [good first issue](https://github.com/HackGT/registration/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22). Feel free to ask questions to clarify things, determine the best way to implement a new feature or bug fix, or anything else!

### Tips

Expand All @@ -140,4 +106,4 @@ If you have some time and want to help us out with development, thank you! You c

## License

Copyright &copy; 2018 HackGT. Released under the MIT license. See [LICENSE](LICENSE) for more information.
Copyright &copy; 2019 HackGT. Released under the MIT license. See [LICENSE](LICENSE) for more information.
5 changes: 0 additions & 5 deletions api.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,6 @@ type User {
name: String!
# User's email
email: String!
# If the user's email is a verified email
email_verified: Boolean!
# Login method(s) this user uses (merged by email address)
login_methods: [String!]!

# If the user has admin privileges
admin: Boolean!
Expand Down Expand Up @@ -156,4 +152,3 @@ type File {
# The formatted size of the file in human-readable units
size_formatted: String!
}

31 changes: 6 additions & 25 deletions client/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,6 @@ <h2>Users</h2>
<th>Name</th>
<th>Email</th>
<th>Status</th>
<th>Log in method</th>
</thead>
<tbody></tbody>
</table>
Expand All @@ -122,14 +121,10 @@ <h2>Users</h2>
<!-- Email -->
<td class="email">
<span></span>
<i class="fa fa-check" title="Verified email" aria-hidden="true"></i>
<i class="fa fa-exclamation-triangle" title="Unverified email" aria-hidden="true"></i>
<i class="fa fa-asterisk" title="Admin" aria-hidden="true"></i>
</td>
<!-- Status -->
<td class="status"></td>
<!-- Login method(s) -->
<td class="login-method"></td>
</tr>
</template>
</section>
Expand Down Expand Up @@ -183,8 +178,6 @@ <h2>Applicants</h2>
<!-- Email -->
<td class="email">
<span></span>
<i class="fa fa-check" title="Verified email" aria-hidden="true"></i>
<i class="fa fa-exclamation-triangle" title="Unverified email" aria-hidden="true"></i>
<i class="fa fa-asterisk" title="Admin" aria-hidden="true"></i>
</td>
<!-- Application branch -->
Expand Down Expand Up @@ -350,22 +343,6 @@ <h5>List of variables:</h5>
</ul>
</div>
</div>
<div class="row">
<div class="col-12">
<h4>Change login methods</h4>
</div>
</div>
<div class="row row-flex">
{{#each settings.loginMethodsInfo}}
<div class="col-4 auth-method" data-raw-name="{{this.raw}}">
<h5>{{this.name}}</h5>
<select>
<option value="enabled" {{#if this.enabled}}selected{{/if}}>Enabled</option>
<option value="disabled" {{#unless this.enabled}}selected{{/unless}}>Disabled</option>
</select>
</div>
{{/each}}
</div>
<h4><code>config.json</code> options</h4>
<div class="row">
<div class="col-4">
Expand All @@ -382,14 +359,18 @@ <h4><code>config.json</code> options</h4>
</div>
</div>
<div class="row">
<div class="col-6">
<div class="col-4">
<label>Upload directory (from <code>config.json</code>):</label>
<input type="text" value="{{config.uploadDirectoryRaw}}" disabled />
</div>
<div class="col-6">
<div class="col-4">
<label>Upload directory (resolved):</label>
<input type="text" value="{{config.uploadDirectoryResolved}}" disabled />
</div>
<div class="col-4">
<label>Preconfigured admins:</label>
<input type="text" value="{{config.admins}}" disabled />
</div>
</div>
<div class="row">
<div class="col-12">
Expand Down
6 changes: 0 additions & 6 deletions client/css/admin.css
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,6 @@ table td:last-child {
td.email > i.fa {
display: none;
}
td.email.verified > i.fa-check {
display: inline;
}
td.email.notverified > i.fa-exclamation-triangle {
display: inline;
}
td.email.admin > i.fa-asterisk {
display: inline;
}
Expand Down
113 changes: 15 additions & 98 deletions client/css/login.css
Original file line number Diff line number Diff line change
@@ -1,98 +1,15 @@
h1 {
margin-bottom: 64px;
text-align: center;
}
a > i {
margin-right: 10px;
transform: scale(1.5);
}
a.github {
color: white;
background-color: #444444;
}
a.google {
color: white;
background-color: #4285F4;
}
a.facebook {
color: white;
background-color: #3b5998;
}
a.gatech {
color: black;
background-color: #eeb211;
}
#error, #success {
text-align: center;
margin-top: 1em;
font-size: 2rem;
margin-bottom: 1em;
color: white;
padding: 10px;
border-radius: 5px;
}
#error {
background-color: rgba(255, 65, 54, 0.85);
}
#success {
background-color: #3D9970;
}
#error:empty, #success:empty {
display: none;
}

main {
display: flex;
flex-direction: column-reverse;
align-items: center;
}
main > div {
box-sizing: border-box;
width: 100%;
display: none;
}
main > .active {
display: block;
}

.simple-methods {
display: flex !important;
flex-direction: column;
}

.unit {
display: flex;
align-items: center;
flex-direction: column;
}
.unit > *:first-child {
width: 125px;
}
#additional-logins {
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
margin-bottom: 10px;
font-size: 85%;
}

/* Desktop styles */
@media only screen and (min-width: 700px) {
main {
flex-direction: row;
}
main > * {
width: 50%;
}
main > .active.border {
border-right: 1px dashed #333030;
padding-right: 15px;
}
main > .active:last-of-type {
padding-left: 10px;
}
.unit, #additional-logins {
flex-direction: row;
}
}
#error {
text-align: center;
margin-top: 1em;
font-size: 2rem;
margin-bottom: 1em;
color: white;
padding: 10px;
border-radius: 5px;
background-color: rgba(255, 65, 54, 0.85);
}
.btn {
display: block;
width: 100px;
margin: 0 auto;
}
30 changes: 0 additions & 30 deletions client/forgotpassword.html

This file was deleted.

0 comments on commit 5aacf38

Please sign in to comment.