GithubHelp home page GithubHelp logo

hackgt / registration Goto Github PK

View Code? Open in Web Editor NEW
6.0 7.0 1.0 6.44 MB

Powerful and extensible registration system for hackathons and other large events

Home Page: https://registration.hack.gt

License: MIT License

TypeScript 68.36% HTML 17.50% CSS 8.57% Shell 0.37% Dockerfile 0.15% Pug 5.05%
registration hackathon hackgt georgia-tech graphql

registration's Introduction

HackGT Registration

Powerful and extensible registration system for hackathons and other large events

Check it out running in production for HackGT 4: New Heights!

HackGT 4: New Heights

Registration displaying the HackGT 4: New Heights participant application with the custom HackGT 4 dark theme.

Features

  • Seamless OAuth and local signup logins with automatic email verification via 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, 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
    • Full email customization using a built-in HTML / Markdown editor with live preview and variable interpolation
    • Ability to view settings from config.json or environment variables that cannot be changed while the app is running

  • Fully configurable and customizable without touching any code
    • Question structure is defined in questions.json and loaded dynamically without having to edit any HTML or JS code
      • Text, phone number, date, URL, and file inputs, checkboxes, radio buttons, select dropdowns, and textareas are all supported
      • Common attributes like placeholders, "other" options, and required questions are supported
      • Text blocks can be attached to questions and stacked. Custom footer text above the submit button is also supported.
      • Works with an unlimited number of questions sets (known as branches) when applying and confirming (e.g. HackGT 4 has participant, mentor, and volunteer applications)
    • Support for custom storage engines for file uploads
      • Comes with disk (default) and Amazon S3 storage engines
    • Email content can be written in HTML or Markdown directly from the admin panel with live previews for the generated HTML and text-only emails
      • Custom email styles are also fully supported
      • Variable interpolation is available for details like user's name, user's email, user's team name, event name, application branch, and confirmation branch.
    • Themes can be configured by editing theme.css (full theming engine planned)

Building and running

First, make sure that you have a MongoDB server up and running and a recent version of Node.js installed. Once your config.json or environment variables are set, you can be up and running in less than 30 seconds:

To build and run the server:

# Install dependencies
npm install
# Build question type definitions for TypeScript from the questions schema and compile
npm run build
# Run server (check the logs for the port and any warning information)
npm start

Visit http://localhost:3000 and you're good to go!

Deployment

A 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).

Environment Variable Description
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/registration)
VERSION_HASH The Git short hash used to identify the current commit (default: parsed automatically from the .git folder, if it exists)
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)
GROUND_TRUTH_URL Base URL of 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 <[email protected]>)
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 (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. (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.
HELPSCOUT_INTEGRATION_ENABLED Whether to enable the backend API endpoint that can provide a dynamic app for Help Scout (default: false)
HELPSCOUT_INTEGRATION_SECRET_KEY A random, 40-character long string of letters, numbers, and symbols. Must also be entered in Help Scout; see the Setting Up Help Scout integration section for more information. (required if Help Scout integration is enabled)
HELPSCOUT_BEACON_ENABLED Whether to show the Help Scout Beacon on certain frontend pages (default: false)
HELPSCOUT_BEACON_ID Unique ID for the Beacon provided by Help Scout (required if Beacon functionality is enabled)
HELPSCOUT_BEACON_SUPPORT_HISTORY_SECRET_KEY Secret key provided by Help Scout for the Beacon Support History option (required if Beacon functionality is enabled)

Contributing

If you happen to find a bug or have a feature you'd like to see implemented, please file an issue.

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 or good first issue. Feel free to ask questions to clarify things, determine the best way to implement a new feature or bug fix, or anything else!

Tips

  • Please try your best to follow the existing coding styles and conventions.
  • Use the latest version of TypeScript
  • Use TypeScript's type annotations whenever possible and Promises for asynchronous operations in conjunction with ES7 async/await (TypeScript's transpilation allows for the use of these features even on platforms that don't support or entirely support ES6 and ES7).
  • We also have TSLint config to catch most style errors or inconsistencies. Sometimes, however, it's necessary to break these rules to get something to work. First, consider if there might be a better way of tackling the problem so that disabling TSLint isn't required. Only if there isn't should you disable TSLint on a line or section basis. Never disable for entire files.
  • Don't overuse TypeScript's non-null assertion operator (the ! after expressions). A value being null is something you should check for and not simply disregard. The preferred way to deal with possibly null values is to check with if (value) {} and fail gracefully if it is not truthy. The TypeScript compiler is usually smart enough to know when you do this, but in more complex cases, an object already checked for non-null status will be reported as possibly null. In this case, you should use the non-null assertion operator.
  • Make sure your branch builds without warnings or errors (including those from TSLint) before committing. Automatic builds are set up with Travis CI and will be marked failed if your code doesn't compile.
  • Use descriptive commit messages that begin with an imperative verb, are properly capitalized, spelled correctly, descriptive, and do not exceed 72 characters. For commits with additional detail, include this in the description and not the main message (you can do this by running git commit with no flags and entering your title, two new lines, and then your description). Descriptions can be as long as necessary.

License

Copyright ยฉ 2020 HackGT. Released under the MIT license. See LICENSE for more information.

Help Scout

Registration includes two features to enable deep integration with Help Scout, a service desk solution, allowing us to provide better support to users requesting support.

  • The Help Scout Integration allows registration to serve a Dynamic App for Help Scout to show additional information about a user's application to a specific event, based on the email address they sent the email from.
  • The Help Scout Beacon adds a small widget to user-facing pages requiring authentication making it super easy to send an email asking for help, engage in live chat support (if enabled), or view knowledge base articles (if enabled).

Help Scout Integration

(Note: The Help Scout dynamic app integration will not work if registration is being hosted from localhost. In other words, you can't test local changes to the Help Scout integration functionality in registration and view them in Help Scout.)

To setup Help Scout integration:

  1. Configure the 2 required environment variables for Help Scout integration, starting with HELPSCOUT_INTEGRATION
  2. Create a new custom app in Help Scout
  3. For Content Type, choose Dynamic Content
  4. For Callback Url, enter <URL to your registration instance>/api/helpscout/userInfo
  5. For Secret Key, enter the exact same value as set in the HELPSCOUT_INTEGRATION_SECRET_KEY environment variable
  6. Once you get the integration working, turn off Debug Mode in Help Scout.
  7. Pick the mailboxes you want the registration integration to appear in.

Note: If the Integration Secret Key is missing or empty but Help Scout Integration is enabled, the feature will be disabled automatically.

The Help Scout Integration can optionally show selected answers to questions from a user's application or confirmation forms. You can indicate which questions to show in Help Scout using by adding showInHelpScout: true to any question in your questions.json file (see example in the question.json included in this repo).

Help Scout Beacon

To setup the Help Scout Beacon:

  1. Make sure the HELPSCOUT_BEACON_ENABLED environment variable is set to true.
  2. In Help Scout, go to Manage > Beacons and find or create a new Beacon.
  3. First, find the Beacon ID. Go to the Installation tab of the Beacon settings and look for the part of the code (near the bottom) that looks like window.Beacon('init', '<THIS IS THE BEACON ID>').
  4. Set the HELPSCOUT_BEACON_ID environment variable to the Beacon ID you just found.
  5. Now go to the Contact settings page for your Beacon.
  6. In the Contact Form setting, turn on the Support history security setting.
  7. A secure key will appear. Set the HELPSCOUT_BEACON_SUPPORT_HISTORY_SECRET_KEY to this value.
  8. That's all the required configuration on registration's end. However, make sure you check out all of the available customization options for Beacons available in Help Scout. You can change the settings remotely through Help Scout without changing any code or configuration in registration!

Note: if either of the required Beacon settings is missing or empty, the Beacon functionality will be automatically disabled.

registration's People

Contributors

ajliu avatar anish2 avatar bunsenmcdubbs avatar dependabot[bot] avatar ehsanmasdar avatar emersonford avatar evan10s avatar illegalprime avatar kexin-zhang avatar mjkaufer avatar petschekr avatar stephanie-a avatar sthomas313-gatech avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

registration's Issues

Provide a route to edit past responses.

Make a route that is a secret to everyone but the user who registered, e.g. it can be the base64-encoding of the user ID such as:

hack.gt/register/edit/124521141341aaffff

This will load the registration questions with the corresponding responses, and allow the user to submit again.

Make the registration page actually good

The registration page should be usable and aesthetic.
Improve or make the current/nonexistent handlebars template for the registration page to make it actually good.

Feel free to use any CSS framework you see fit.

Also be sure to include check marks, or whatever you think is right as initially hidden elements to provide UI feedback on if the input is correct or not. (if a phone number is in a valid form). The checking of this will be handled by #5

Accept / reject attendees

Implemented as part of the admin panel. Needs to send out emails and allow access to a second evaluation form.

InfluxDB Integration

Integrate InfluxDB to export time series metrics for visualization in other services such as Grafana.

Notify the user he/she can edit his/her responses.

Whether by email or something else, or on the successful submission page, provide a link the user can visit to change his responses. The actual mechanics of editing responses is a separate issue described here: #7 .

This should be completed after #7

Missing Favicon

This is the lowest possible priority.

Preferably make this a configurable setting etc.

Authenticate users with OAuth or some other method

To authenticate users, we should use OAuth authentication with providers such as Google and GitHub. This can easily be done with a library such as Passport. We should prefer this kind of authentication over username / password because:

  • We won't have to worry about properly securing passwords (proper key derivation algorithm, salting, etc.)
  • Easier registration process because the user won't have to create yet another username and password combination
  • Email service (such as SendGrid) not required. When using a username / password combination, there has to be some sort of process in place for resetting forgotten passwords.

The only drawback that I can think of is that creating an initial admin user is a trickier problem to solve.

Roadmap to v2, Public Release

soon we'll want to open source this and let other people use it, so we should think about how we want to generalize it to everyone, this is a bug to brainstorm, the individual tasks should be made into separate bugs & PRs, some ideas include:

  • Custom CSS file to make it match other apps people are using this with
  • i18n
  • customize text #38
  • Modularized auth methods #36
  • Create admins in the admin screen #40
  • File uploads #46

what else do we need?

Send rejection emails

We need a way to notify people who haven't been accepted. Possibly also add multiple states like accepted, no decision, and rejected instead of the accepted / not accepted options currently in place.

Dashboard text should be admin configurable

Make the text in the dashboard (somewhat) configurable by admins.

  1. Will need different text for different stages (applied, accepted, confirmed).
  2. Will need different text for different applicants (student, mentor, chaperone etc.)
    Note: depending on our architecture, this might be pretty hard?

Configurability:

  1. Partially configurable. Default will just show a sentence about when applications are due. Any custom stuff will appear underneath the "due date"
  2. Fully configurable with some kind of templating. Available vars include
    1. (Basic) user info (name, email, applicant type)
    2. Due date

Bonus points:

  1. Markdown support
  2. Emoji support (probably comes for free)

Navigation to/between applications

When there are multiple applications (aka our case with student, mentor, and chaperone), we should add in certain UI tweaks to make it friendlier.

  1. [Beginner Friendly] Let users go back to the "Choose what you want to apply as" screen. Yes, they can just go back in their browser but that's not always intuitive (also what if you clicked a link...)

  2. [Not as beginner friendly] Enable "deep linking" aka allow someone to be linked directly to a specific application.
    Use case:

    1. A mentor link would be https://registration.hack.gt/apply/mentor
    2. New user would be redirected to a login/signup screen
    3. When authenticated, they are navigated directly to the mentor application (rather than dashboard or generic application screen)

Better exporting support

The current preliminary work merged in d15217a is only to support check in for the HackGT Catalyst event. Ideally we want to make the current export button a menu with checkboxes for the branches and options for applied/accepted/not complete and then maybe options for which fields to export from the application

Strategically Place Logs

We want to log when the user does anything, then we can look back and see some trends and even do some AB testing! I'd like to use this issue to make sure everyone has a voice on what they want tracked.

cc @petschekr @bunsenmcdubbs

What I'm thinking so far:

  • visiting
  • creating an account
  • starting registration
  • completing registration

And what to log:

  • any demographic information available
  • a unique identification when available
  • time
  • location

Anyone else have any other ideas? Assigning @kexin-zhang on this since she's the master of metrics!

Record the responses in Mongo

Assume that you have a JSON configuration of the registration questions equivalent to the config used in #1 , like so:

questions:
  - type: text
    text: What's good?

  - type: select
    text: 'Dietary Restrictions:'
    options:
      - Vegan
      - Vegetarian
      - Kosher
      - Paleo

Use this configuration to make a schema for mongo at startup and connect to mongo.

Create a route that will accept the HTML form input, verify it against the schema, and store it in mongo.

Return a success page in the event the data is successfully recorded into mongo.
Return a failure if this procedure encounters a fatal error.

Add unit tests

Since this is mostly a server-side app, it lends itself well to unit tests on the API. If you decide to tackle this, please structure them like in Ultimate-Checkin (i.e. using mocha, supertest, and chai). Also, make sure that the tests are integrated and automatically run by the Travis CI build.

Add a legend in the admin screen

As admin, viewing a list of all users, I see stars and checkmarks next to user emails. I assume:

  • stars = admins
  • checkmarks = confirmed user? submitted application?

There should be a small legend at the top/side so its more explicit.

Team management system

The team link in the header nav menu doesn't currently go anywhere. We need a team management system for hackathons and other events post-Catalyst. The number of team members and whether team management is enabled or disabled to be configurable from the admin panel.

GitHub login user validation failed

Comes out as a plain text MongooseError...user should be able to log in again

MongooseError: User validation failed
    at ValidationError (/usr/src/checkin/node_modules/mongoose/lib/error/validation.js:23:11)
    at model.Document.invalidate (/usr/src/checkin/node_modules/mongoose/lib/document.js:1535:32)
    at /usr/src/checkin/node_modules/mongoose/lib/document.js:1410:17
    at validate (/usr/src/checkin/node_modules/mongoose/lib/schematype.js:707:7)
    at /usr/src/checkin/node_modules/mongoose/lib/schematype.js:752:11
    at Array.forEach (native)
    at SchemaString.SchemaType.doValidate (/usr/src/checkin/node_modules/mongoose/lib/schematype.js:712:19)
    at /usr/src/checkin/node_modules/mongoose/lib/document.js:1408:9
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickCallback (internal/process/next_tick.js:98:9)

Non-OAuth login method

Traditional username / password scheme for times when users might not have accounts on GitHub / Google / Facebook. Let's use this.

Form submission bug in non-Chrome browsers

Submitting the registration form in a non-Chrome browser (tested with Microsoft Edge and Firefox) will successfully submit the form but the browser won't stop submitting the form to a non-existant endpoint and will send the user to a page that says something like Cannot POST /apply/mentor.

Also affects the admin settings form

Serve the registration page

Assume you have a JSON object with the configuration for the registration page is a format similar to:

questions:
  - type: text
    text: What's good?

  - type: select
    text: 'Dietary Restrictions:'
    options:
      - Vegan
      - Vegetarian
      - Kosher
      - Paleo

Use this configuration to render and cache a handlebars template that is the HTML of the registration page. Finally add a route that serves this cached page.

Create the success and failure pages.

We need pages that represent:

  1. a response being successfully recorded on the server
  2. a server failure

these will be served after the user submits the registration.

HackGT Catalyst registration questions

We need to replace the current debugging questions.json configuration with the actual registration form to be used for the HackGT Catalyst high school hackathon.

Basic admin panel

Probably want to break this down into the following sections:

  • Stats
    • Admitted / confirmed / denied
    • Demographics
  • Users
    • Table of users
    • Accept / deny users
  • Settings
    • Open / close registration
    • Registration and confirmation close date
    • Email content editing
    • Enable / disable teams
    • Configure max team size (if any)

Create admins from admin screen

Give the ability to set (and un-set) users as admins in the admin screen so config changes/app restarts aren't necessary.

Support file uploads in form

This one is going to be tricky (not too bad, just harder than the other form fields)... We need to be able to support file uploads in the application form. Development for this can come in 2 stages.

First, support file uploads and save to disk.

  • configure a location on disk to save files (absolute or relative path - absolute is encouraged for production, relative makes it easier for development)
  • save user's file uploads in a directory structure inside the uploads directory that supports multiple file upload fields
    ex) uploads/<question1/question2/question3>/<user_id>.<file_ext>
  • any API requests for getting application/user data should indicate that the user has a file uploaded for that field but not include the file itself. Create a separate endpoint for file uploads.
    ex) (and this is a totally wild guess, please change as appropriate) GET /api/files/<question_id>/<user_id>

There are several considerations for this approach:

  • Questions now need id's (or some identification method to support multiple file upload fields in a form)
  • how to support multiple files for a single field? zip all files when downloading on GET requests? consider changing directory structure to:
    uploads/<question_id>/<user_id>/<file_name>

The second stage will be considerably... fancier. Modularize/decouple the actual file upload handling process. ex) What if you don't want to upload to a local directory? Enable "pluginability" (upload to S3, Google Drive API etc.)?

Client-side validation

The configuration file for the questions could have some restrictions, or could require preprocessing (such as when uploading a resume maybe it gets sent to an S3 bucket or maybe its just converted to base64). This will be the same format as in #1 and #2 :

questions:
  - type: text
    pattern: [0-9]{10}
    text: Phone #

  - type: file
    text: Resume
    size-limit: 1kb

Since each type of question will likely have its own validation parameters, simply start with validating text with a regex and displaying UI feedback to the user, disallowing submission if the input is invalid.

Timezone issues

I noticed this when the server's timezone was different from my computer's.

Steps to replicate:

  1. Set your computer timezone to one different from the server (aka not EST).
  2. Go to the admin page and change the application opening/closing time
  3. Save.

You'll notice that the time that in the input box changes (probably by the timezone difference between server and client ... or UTC?). This hop will actually let you continually move the time forward/backwards if you just click "save" over and over.

Solutions:

  1. Ensure that timezones are known in the client, server etc.
  2. Always convert to/from local time OR
  3. Display the timezone
    ex: ... 3pm EST
  • Bonus points if the timezone is only displayed when it is different

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.