diff --git a/client/less/main.less b/client/less/main.less index db9a804e05..bbf9249e6b 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -35,14 +35,46 @@ pre.wrappable { word-wrap: break-word; /* IE 5+ */ } -//input[type=checkbox] { -// /* Double-sized Checkboxes */ -// -ms-transform: scale(2); /* IE */ -// -moz-transform: scale(2); /* FF */ -// -webkit-transform: scale(2); /* Safari and Chrome */ -// -o-transform: scale(2); /* Opera */ -// padding: 10px; -//} +.checkbox label:after { + content: ''; + display: table; + clear: both; +} + +.checkbox .cr { + position: relative; + display: inline-block; + border: 1px solid #a9a9a9; + border-radius: .25em; + width: 1.3em; + height: 1.3em; + float: left; + margin-right: .5em; +} + +.checkbox .cr .cr-icon { + position: absolute; + font-size: .8em; + line-height: 0; + top: 50%; + left: 15%; +} + +.checkbox label input[type="checkbox"] { + display: none; +} + +.checkbox label input[type="checkbox"]+.cr>.cr-icon { + opacity: 0; +} + +.checkbox label input[type="checkbox"]:checked+.cr>.cr-icon { + opacity: 1; +} + +.checkbox label input[type="checkbox"]:disabled+.cr { + opacity: .5; +} .btn-group { border-color: @brand-primary; diff --git a/common/models/User-Identity.js b/common/models/User-Identity.js index 3fb7c30a40..eeaa59f6a6 100644 --- a/common/models/User-Identity.js +++ b/common/models/User-Identity.js @@ -4,8 +4,7 @@ import dedent from 'dedent'; import { getSocialProvider, - getUsernameFromProvider, - createUserUpdatesFromProfile + getUsernameFromProvider } from '../../server/utils/auth'; import { observeMethod, observeQuery } from '../../server/utils/rx'; import { wrapHandledError } from '../../server/utils/create-handled-error.js'; @@ -48,84 +47,100 @@ export default function(UserIdent) { }, include: 'user' }; - return UserIdent.findOne$(query) - .flatMap(identity => { - if (!identity) { - throw wrapHandledError( - new Error('user identity account not found'), - { - message: dedent` - New accounts can only be created using an email address. - Please create an account below - `, - type: 'info', - redirectTo: '/signup' - } - ); - } - const modified = new Date(); - const user = identity.user(); - if (!user) { - const username = getUsernameFromProvider(provider, profile); - return observeQuery( + + if (provider === 'auth0') { + + const email = profile.emails[0].value; + return User.findOne$({ where: { email } }) + .flatMap(user => { + if (!user) { + return User.create$({ email }); + } + return Observable.of(user); + }) + .subscribe( + ( user ) => cb(null, user, null, null), + cb + ); + + } else { + + return UserIdent.findOne$(query) + .flatMap(identity => { + if (!identity) { + throw wrapHandledError( + new Error('user identity account not found'), + { + message: dedent` + New accounts can only be created using an email address. + Please create an account below + `, + type: 'info', + redirectTo: '/signup' + } + ); + } + const modified = new Date(); + const user = identity.user(); + if (!user) { + const username = getUsernameFromProvider(provider, profile); + return observeQuery( + identity, + 'updateAttributes', + { + isOrphaned: username || true + } + ) + .do(() => { + throw wrapHandledError( + new Error('user identity is not associated with a user'), + { + type: 'info', + redirectTo: '/signup', + message: dedent` + The user account associated with the ${provider} user ${username || 'Anon'} + no longer exists. + ` + } + ); + }); + } + + // identity already exists + // find user and log them in + identity.credentials = credentials; + const attributes = { + // we no longer want to keep the profile + // this is information we do not need or use + profile: null, + credentials: credentials, + modified + }; + const updateIdentity = observeQuery( identity, 'updateAttributes', + attributes + ); + const createToken = observeQuery( + AccessToken, + 'create', { - isOrphaned: username || true + userId: user.id, + created: new Date(), + ttl: user.constructor.settings.ttl } - ) - .do(() => { - throw wrapHandledError( - new Error('user identity is not associated with a user'), - { - type: 'info', - redirectTo: '/signup', - message: dedent` - The user account associated with the ${provider} user ${username || 'Anon'} - no longer exists. - ` - } - ); - }); - } - const updateUser = User.update$( - { id: user.id }, - createUserUpdatesFromProfile(provider, profile) - ).map(() => user); - // identity already exists - // find user and log them in - identity.credentials = credentials; - const attributes = { - // we no longer want to keep the profile - // this is information we do not need or use - profile: null, - credentials: credentials, - modified - }; - const updateIdentity = observeQuery( - identity, - 'updateAttributes', - attributes + ); + return Observable.combineLatest( + Observable.of(user), + updateIdentity, + createToken, + (user, identity, token) => ({ user, identity, token }) + ); + }) + .subscribe( + ({ user, identity, token }) => cb(null, user, identity, token), + cb ); - const createToken = observeQuery( - AccessToken, - 'create', - { - userId: user.id, - created: new Date(), - ttl: user.constructor.settings.ttl - } - ); - return Observable.combineLatest( - updateUser, - updateIdentity, - createToken, - (user, identity, token) => ({ user, identity, token }) - ); - }) - .subscribe( - ({ user, identity, token }) => cb(null, user, identity, token), - cb - ); + } }; } diff --git a/hosted-templates/hosted-pages/login.html b/hosted-templates/hosted-pages/login.html new file mode 100644 index 0000000000..4d1b4e6381 --- /dev/null +++ b/hosted-templates/hosted-pages/login.html @@ -0,0 +1,462 @@ + + + + +
+ + + +`, ``, and ``.
-@font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace;
-@font-family-base: @font-family-sans-serif;
-
-@font-size-base: 15px;
-@font-size-large: ceil((@font-size-base * 1.25)); // ~18px
-@font-size-small: ceil((@font-size-base * 0.85)); // ~12px
-
-@font-size-h1: floor((@font-size-base * 2.6)); // ~36px
-@font-size-h2: floor((@font-size-base * 2.15)); // ~30px
-@font-size-h3: ceil((@font-size-base * 1.7)); // ~24px
-@font-size-h4: ceil((@font-size-base * 1.25)); // ~18px
-@font-size-h5: @font-size-base;
-@font-size-h6: ceil((@font-size-base * 0.85)); // ~12px
-
-//** Unit-less `line-height` for use in components like buttons.
-@line-height-base: 1.428571429; // 20/14
-//** Computed "line-height" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.
-@line-height-computed: floor((@font-size-base * @line-height-base)); // ~20px
-
-//** By default, this inherits from the ``.
-@headings-font-family: @font-family-base;
-@headings-font-weight: 400;
-@headings-line-height: 1.1;
-@headings-color: inherit;
-
-
-//== Iconography
-//
-//## Specify custom location and filename of the included Glyphicons icon font. Useful for those including Bootstrap via npm.
-
-//** Load fonts from this directory.
-@icon-font-path: "../fonts/";
-//** File name for all font files.
-@icon-font-name: "glyphicons-halflings-regular";
-//** Element ID within SVG icon file.
-@icon-font-svg-id: "glyphicons_halflingsregular";
-
-
-//== Components
-//
-//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).
-
-@padding-base-vertical: 10px;
-@padding-base-horizontal: 15px;
-
-@padding-large-vertical: 18px;
-@padding-large-horizontal: 27px;
-
-@padding-small-vertical: 6px;
-@padding-small-horizontal: 9px;
-
-@padding-xs-vertical: 1px;
-@padding-xs-horizontal: 5px;
-
-@line-height-large: 1.33;
-@line-height-small: 1.5;
-
-@border-radius-base: 4px;
-@border-radius-large: 6px;
-@border-radius-small: 3px;
-
-//** Global color for active items (e.g., navs or dropdowns).
-@component-active-color: #fff;
-//** Global background color for active items (e.g., navs or dropdowns).
-@component-active-bg: @brand-primary;
-
-//** Width of the `border` for generating carets that indicator dropdowns.
-@caret-width-base: 4px;
-//** Carets increase slightly in size for larger components.
-@caret-width-large: 5px;
-
-
-//== Tables
-//
-//## Customizes the `.table` component with basic values, each used across all table variations.
-
-//** Padding for ``s and ` `s.
-@table-cell-padding: 8px;
-//** Padding for cells in `.table-condensed`.
-@table-condensed-cell-padding: 5px;
-
-//** Default background color used for all tables.
-@table-bg: transparent;
-//** Background color used for `.table-striped`.
-@table-bg-accent: #f9f9f9;
-//** Background color used for `.table-hover`.
-@table-bg-hover: @gray-lighter;
-@table-bg-active: @table-bg-hover;
-
-//** Border color for table and cell borders.
-@table-border-color: @gray-lighter;
-
-
-//== Buttons
-//
-//## For each of Bootstrap's buttons, define text, background and border color.
-
-@btn-font-weight: normal;
-
-@btn-default-color: #fff;
-@btn-default-bg: @gray;
-@btn-default-border: @btn-default-bg;
-
-@btn-primary-color: @btn-default-color;
-@btn-primary-bg: @brand-primary;
-@btn-primary-border: @btn-primary-bg;
-
-@btn-success-color: @btn-default-color;
-@btn-success-bg: @brand-success;
-@btn-success-border: @btn-success-bg;
-
-@btn-info-color: @btn-default-color;
-@btn-info-bg: @brand-info;
-@btn-info-border: @btn-info-bg;
-
-@btn-warning-color: @btn-default-color;
-@btn-warning-bg: @brand-warning;
-@btn-warning-border: @btn-warning-bg;
-
-@btn-danger-color: @btn-default-color;
-@btn-danger-bg: @brand-danger;
-@btn-danger-border: @btn-danger-bg;
-
-@btn-link-disabled-color: @gray-light;
-
-
-//== Forms
-//
-//##
-
-//** `` background color
-@input-bg: #fff;
-//** `` background color
-@input-bg-disabled: @gray-lighter;
-
-//** Text color for ``s
-@input-color: @text-color;
-//** `` border color
-@input-border: #dce4ec;
-
-// TODO: Rename `@input-border-radius` to `@input-border-radius-base` in v4
-//** Default `.form-control` border radius
-@input-border-radius: @border-radius-base;
-//** Large `.form-control` border radius
-@input-border-radius-large: @border-radius-large;
-//** Small `.form-control` border radius
-@input-border-radius-small: @border-radius-small;
-
-//** Border color for inputs on focus
-@input-border-focus: @brand-primary;
-
-//** Placeholder text color
-@input-color-placeholder: #acb6c0;
-
-//** Default `.form-control` height
-@input-height-base: (@line-height-computed + (@padding-base-vertical * 2) + 2);
-//** Large `.form-control` height
-@input-height-large: (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);
-//** Small `.form-control` height
-@input-height-small: (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);
-
-@legend-color: @text-color;
-@legend-border-color: transparent;
-
-//** Background color for textual input addons
-@input-group-addon-bg: @gray-lighter;
-//** Border color for textual input addons
-@input-group-addon-border-color: @input-border;
-
-//** Disabled cursor for form controls and buttons.
-@cursor-disabled: not-allowed;
-
-
-//== Dropdowns
-//
-//## Dropdown menu container and contents.
-
-//** Background for the dropdown menu.
-@dropdown-bg: #fff;
-//** Dropdown menu `border-color`.
-@dropdown-border: rgba(0,0,0,.15);
-//** Dropdown menu `border-color` **for IE8**.
-@dropdown-fallback-border: #ccc;
-//** Divider color for between dropdown items.
-@dropdown-divider-bg: #e5e5e5;
-
-//** Dropdown link text color.
-@dropdown-link-color: @gray-dark;
-//** Hover color for dropdown links.
-@dropdown-link-hover-color: #fff;
-//** Hover background for dropdown links.
-@dropdown-link-hover-bg: @dropdown-link-active-bg;
-
-//** Active dropdown menu item text color.
-@dropdown-link-active-color: #fff;
-//** Active dropdown menu item background color.
-@dropdown-link-active-bg: @component-active-bg;
-
-//** Disabled dropdown menu item background color.
-@dropdown-link-disabled-color: @text-muted;
-
-//** Text color for headers within dropdown menus.
-@dropdown-header-color: @text-muted;
-
-//** Deprecated `@dropdown-caret-color` as of v3.1.0
-@dropdown-caret-color: #000;
-
-
-//-- Z-index master list
-//
-// Warning: Avoid customizing these values. They're used for a bird's eye view
-// of components dependent on the z-axis and are designed to all work together.
-//
-// Note: These variables are not generated into the Customizer.
-
-@zindex-navbar: 1000;
-@zindex-dropdown: 1000;
-@zindex-popover: 1060;
-@zindex-tooltip: 1070;
-@zindex-navbar-fixed: 1030;
-@zindex-modal: 1040;
-
-
-//== Media queries breakpoints
-//
-//## Define the breakpoints at which your layout will change, adapting to different screen sizes.
-
-// Extra small screen / phone
-//** Deprecated `@screen-xs` as of v3.0.1
-@screen-xs: 480px;
-//** Deprecated `@screen-xs-min` as of v3.2.0
-@screen-xs-min: @screen-xs;
-//** Deprecated `@screen-phone` as of v3.0.1
-@screen-phone: @screen-xs-min;
-
-// Small screen / tablet
-//** Deprecated `@screen-sm` as of v3.0.1
-@screen-sm: 768px;
-@screen-sm-min: @screen-sm;
-//** Deprecated `@screen-tablet` as of v3.0.1
-@screen-tablet: @screen-sm-min;
-
-// Medium screen / desktop
-//** Deprecated `@screen-md` as of v3.0.1
-@screen-md: 992px;
-@screen-md-min: @screen-md;
-//** Deprecated `@screen-desktop` as of v3.0.1
-@screen-desktop: @screen-md-min;
-
-// Large screen / wide desktop
-//** Deprecated `@screen-lg` as of v3.0.1
-@screen-lg: 1200px;
-@screen-lg-min: @screen-lg;
-//** Deprecated `@screen-lg-desktop` as of v3.0.1
-@screen-lg-desktop: @screen-lg-min;
-
-// So media queries don't overlap when required, provide a maximum
-@screen-xs-max: (@screen-sm-min - 1);
-@screen-sm-max: (@screen-md-min - 1);
-@screen-md-max: (@screen-lg-min - 1);
-
-
-//== Grid system
-//
-//## Define your custom responsive grid.
-
-//** Number of columns in the grid.
-@grid-columns: 12;
-//** Padding between columns. Gets divided in half for the left and right.
-@grid-gutter-width: 30px;
-// Navbar collapse
-//** Point at which the navbar becomes uncollapsed.
-@grid-float-breakpoint: @screen-sm-min;
-//** Point at which the navbar begins collapsing.
-@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);
-
-
-//== Container sizes
-//
-//## Define the maximum width of `.container` for different screen sizes.
-
-// Small screen / tablet
-@container-tablet: (720px + @grid-gutter-width);
-//** For `@screen-sm-min` and up.
-@container-sm: @container-tablet;
-
-// Medium screen / desktop
-@container-desktop: (940px + @grid-gutter-width);
-//** For `@screen-md-min` and up.
-@container-md: @container-desktop;
-
-// Large screen / wide desktop
-@container-large-desktop: (1140px + @grid-gutter-width);
-//** For `@screen-lg-min` and up.
-@container-lg: @container-large-desktop;
-
-
-//== Navbar
-//
-//##
-
-// Basics of a navbar
-@navbar-height: 60px;
-@navbar-margin-bottom: @line-height-computed;
-@navbar-border-radius: @border-radius-base;
-@navbar-padding-horizontal: floor((@grid-gutter-width / 2));
-@navbar-padding-vertical: ((@navbar-height - @line-height-computed) / 2);
-@navbar-collapse-max-height: 340px;
-
-@navbar-default-color: #777;
-@navbar-default-bg: @brand-primary;
-@navbar-default-border: transparent;
-
-// Navbar links
-@navbar-default-link-color: #fff;
-@navbar-default-link-hover-color: @brand-success;
-@navbar-default-link-hover-bg: transparent;
-@navbar-default-link-active-color: #fff;
-@navbar-default-link-active-bg: darken(@navbar-default-bg, 10%);
-@navbar-default-link-disabled-color: #ccc;
-@navbar-default-link-disabled-bg: transparent;
-
-// Navbar brand label
-@navbar-default-brand-color: @navbar-default-link-color;
-@navbar-default-brand-hover-color: @navbar-default-link-hover-color;
-@navbar-default-brand-hover-bg: transparent;
-
-// Navbar toggle
-@navbar-default-toggle-hover-bg: darken(@navbar-default-bg, 10%);
-@navbar-default-toggle-icon-bar-bg: #fff;
-@navbar-default-toggle-border-color: darken(@navbar-default-bg, 10%);
-
-
-// Inverted navbar
-// Reset inverted navbar basics
-@navbar-inverse-color: #fff;
-@navbar-inverse-bg: @brand-success;
-@navbar-inverse-border: transparent;
-
-// Inverted navbar links
-@navbar-inverse-link-color: #fff;
-@navbar-inverse-link-hover-color: @brand-primary;
-@navbar-inverse-link-hover-bg: transparent;
-@navbar-inverse-link-active-color: #fff;
-@navbar-inverse-link-active-bg: darken(@navbar-inverse-bg, 5%);
-@navbar-inverse-link-disabled-color: #ccc;
-@navbar-inverse-link-disabled-bg: transparent;
-
-// Inverted navbar brand label
-@navbar-inverse-brand-color: @navbar-inverse-link-color;
-@navbar-inverse-brand-hover-color: @navbar-inverse-link-hover-color;
-@navbar-inverse-brand-hover-bg: transparent;
-
-// Inverted navbar toggle
-@navbar-inverse-toggle-hover-bg: darken(@navbar-inverse-bg, 10%);
-@navbar-inverse-toggle-icon-bar-bg: #fff;
-@navbar-inverse-toggle-border-color: darken(@navbar-inverse-bg, 10%);
-
-
-//== Navs
-//
-//##
-
-//=== Shared nav styles
-@nav-link-padding: 10px 15px;
-@nav-link-hover-bg: @gray-lighter;
-
-@nav-disabled-link-color: @gray-light;
-@nav-disabled-link-hover-color: @gray-light;
-
-//== Tabs
-@nav-tabs-border-color: @gray-lighter;
-
-@nav-tabs-link-hover-border-color: @gray-lighter;
-
-@nav-tabs-active-link-hover-bg: @body-bg;
-@nav-tabs-active-link-hover-color: @brand-primary;
-@nav-tabs-active-link-hover-border-color: @gray-lighter;
-
-@nav-tabs-justified-link-border-color: @gray-lighter;
-@nav-tabs-justified-active-link-border-color: @body-bg;
-
-//== Pills
-@nav-pills-border-radius: @border-radius-base;
-@nav-pills-active-link-hover-bg: @component-active-bg;
-@nav-pills-active-link-hover-color: @component-active-color;
-
-
-//== Pagination
-//
-//##
-
-@pagination-color: #fff;
-@pagination-bg: @brand-success;
-@pagination-border: transparent;
-
-@pagination-hover-color: #fff;
-@pagination-hover-bg: darken(@brand-success, 15%);
-@pagination-hover-border: transparent;
-
-@pagination-active-color: #fff;
-@pagination-active-bg: darken(@brand-success, 15%);
-@pagination-active-border: transparent;
-
-@pagination-disabled-color: @gray-lighter;
-@pagination-disabled-bg: lighten(@brand-success, 15%);;
-@pagination-disabled-border: transparent;
-
-
-//== Pager
-//
-//##
-
-@pager-bg: @pagination-bg;
-@pager-border: @pagination-border;
-@pager-border-radius: 15px;
-
-@pager-hover-bg: @pagination-hover-bg;
-
-@pager-active-bg: @pagination-active-bg;
-@pager-active-color: @pagination-active-color;
-
-@pager-disabled-color: #fff;
-
-
-//== Jumbotron
-//
-//##
-
-@jumbotron-padding: 30px;
-@jumbotron-color: inherit;
-@jumbotron-bg: @gray-lighter;
-@jumbotron-heading-color: inherit;
-@jumbotron-font-size: ceil((@font-size-base * 1.5));
-
-
-//== Form states and alerts
-//
-//## Define colors for form feedback states and, by default, alerts.
-
-@state-success-text: #fff;
-@state-success-bg: @brand-success;
-@state-success-border: @brand-success;
-
-@state-info-text: #fff;
-@state-info-bg: @brand-info;
-@state-info-border: @brand-info;
-
-@state-warning-text: #fff;
-@state-warning-bg: @brand-warning;
-@state-warning-border: @brand-warning;
-
-@state-danger-text: #fff;
-@state-danger-bg: @brand-danger;
-@state-danger-border: @brand-danger;
-
-
-//== Tooltips
-//
-//##
-
-//** Tooltip max width
-@tooltip-max-width: 200px;
-//** Tooltip text color
-@tooltip-color: #fff;
-//** Tooltip background color
-@tooltip-bg: rgba(0,0,0,.9);
-@tooltip-opacity: .9;
-
-//** Tooltip arrow width
-@tooltip-arrow-width: 5px;
-//** Tooltip arrow color
-@tooltip-arrow-color: @tooltip-bg;
-
-
-//== Popovers
-//
-//##
-
-//** Popover body background color
-@popover-bg: #fff;
-//** Popover maximum width
-@popover-max-width: 276px;
-//** Popover border color
-@popover-border-color: rgba(0,0,0,.2);
-//** Popover fallback border color
-@popover-fallback-border-color: #ccc;
-
-//** Popover title background color
-@popover-title-bg: darken(@popover-bg, 3%);
-
-//** Popover arrow width
-@popover-arrow-width: 10px;
-//** Popover arrow color
-@popover-arrow-color: @popover-bg;
-
-//** Popover outer arrow width
-@popover-arrow-outer-width: (@popover-arrow-width + 1);
-//** Popover outer arrow color
-@popover-arrow-outer-color: fadein(@popover-border-color, 5%);
-//** Popover outer arrow fallback color
-@popover-arrow-outer-fallback-color: darken(@popover-fallback-border-color, 20%);
-
-
-//== Labels
-//
-//##
-
-//** Default label background color
-@label-default-bg: @btn-default-bg;
-//** Primary label background color
-@label-primary-bg: @brand-primary;
-//** Success label background color
-@label-success-bg: @brand-success;
-//** Info label background color
-@label-info-bg: @brand-info;
-//** Warning label background color
-@label-warning-bg: @brand-warning;
-//** Danger label background color
-@label-danger-bg: @brand-danger;
-
-//** Default label text color
-@label-color: #fff;
-//** Default text color of a linked label
-@label-link-hover-color: #fff;
-
-
-//== Modals
-//
-//##
-
-//** Padding applied to the modal body
-@modal-inner-padding: 20px;
-
-//** Padding applied to the modal title
-@modal-title-padding: 15px;
-//** Modal title line-height
-@modal-title-line-height: @line-height-base;
-
-//** Background color of modal content area
-@modal-content-bg: #fff;
-//** Modal content border color
-@modal-content-border-color: rgba(0,0,0,.2);
-//** Modal content border color **for IE8**
-@modal-content-fallback-border-color: #999;
-
-//** Modal backdrop background color
-@modal-backdrop-bg: #000;
-//** Modal backdrop opacity
-@modal-backdrop-opacity: .5;
-//** Modal header border color
-@modal-header-border-color: #e5e5e5;
-//** Modal footer border color
-@modal-footer-border-color: @modal-header-border-color;
-
-@modal-lg: 900px;
-@modal-md: 600px;
-@modal-sm: 300px;
-
-
-//== Alerts
-//
-//## Define alert colors, border radius, and padding.
-
-@alert-padding: 15px;
-@alert-border-radius: @border-radius-base;
-@alert-link-font-weight: bold;
-
-@alert-success-bg: @state-success-bg;
-@alert-success-text: @state-success-text;
-@alert-success-border: @state-success-border;
-
-@alert-info-bg: @state-info-bg;
-@alert-info-text: @state-info-text;
-@alert-info-border: @state-info-border;
-
-@alert-warning-bg: @state-warning-bg;
-@alert-warning-text: @state-warning-text;
-@alert-warning-border: @state-warning-border;
-
-@alert-danger-bg: @state-danger-bg;
-@alert-danger-text: @state-danger-text;
-@alert-danger-border: @state-danger-border;
-
-
-//== Progress bars
-//
-//##
-
-//** Background color of the whole progress component
-@progress-bg: @gray-lighter;
-//** Progress bar text color
-@progress-bar-color: #fff;
-//** Variable for setting rounded corners on progress bar.
-@progress-border-radius: @border-radius-base;
-
-//** Default progress bar color
-@progress-bar-bg: @brand-primary;
-//** Success progress bar color
-@progress-bar-success-bg: @brand-success;
-//** Warning progress bar color
-@progress-bar-warning-bg: @brand-warning;
-//** Danger progress bar color
-@progress-bar-danger-bg: @brand-danger;
-//** Info progress bar color
-@progress-bar-info-bg: @brand-info;
-
-
-//== List group
-//
-//##
-
-//** Background color on `.list-group-item`
-@list-group-bg: #fff;
-//** `.list-group-item` border color
-@list-group-border: @gray-lighter;
-//** List group border radius
-@list-group-border-radius: @border-radius-base;
-
-//** Background color of single list items on hover
-@list-group-hover-bg: @gray-lighter;
-//** Text color of active list items
-@list-group-active-color: @component-active-color;
-//** Background color of active list items
-@list-group-active-bg: @component-active-bg;
-//** Border color of active list elements
-@list-group-active-border: @list-group-active-bg;
-//** Text color for content within active list items
-@list-group-active-text-color: lighten(@list-group-active-bg, 40%);
-
-//** Text color of disabled list items
-@list-group-disabled-color: @gray-light;
-//** Background color of disabled list items
-@list-group-disabled-bg: @gray-lighter;
-//** Text color for content within disabled list items
-@list-group-disabled-text-color: @list-group-disabled-color;
-
-@list-group-link-color: #555;
-@list-group-link-hover-color: @list-group-link-color;
-@list-group-link-heading-color: #333;
-
-
-//== Panels
-//
-//##
-
-@panel-bg: #fff;
-@panel-body-padding: 15px;
-@panel-heading-padding: 10px 15px;
-@panel-footer-padding: @panel-heading-padding;
-@panel-border-radius: @border-radius-base;
-
-//** Border color for elements within panels
-@panel-inner-border: @gray-lighter;
-@panel-footer-bg: @gray-lighter;
-
-@panel-default-text: @text-color;
-@panel-default-border: @gray-lighter;
-@panel-default-heading-bg: @gray-lighter;
-
-@panel-primary-text: #fff;
-@panel-primary-border: @brand-primary;
-@panel-primary-heading-bg: @brand-primary;
-
-@panel-success-text: @state-success-text;
-@panel-success-border: @state-success-border;
-@panel-success-heading-bg: @state-success-bg;
-
-@panel-info-text: @state-info-text;
-@panel-info-border: @state-info-border;
-@panel-info-heading-bg: @state-info-bg;
-
-@panel-warning-text: @state-warning-text;
-@panel-warning-border: @state-warning-border;
-@panel-warning-heading-bg: @state-warning-bg;
-
-@panel-danger-text: @state-danger-text;
-@panel-danger-border: @state-danger-border;
-@panel-danger-heading-bg: @state-danger-bg;
-
-
-//== Thumbnails
-//
-//##
-
-//** Padding around the thumbnail image
-@thumbnail-padding: 4px;
-//** Thumbnail background color
-@thumbnail-bg: @body-bg;
-//** Thumbnail border color
-@thumbnail-border: @gray-lighter;
-//** Thumbnail border radius
-@thumbnail-border-radius: @border-radius-base;
-
-//** Custom text color for thumbnail captions
-@thumbnail-caption-color: @text-color;
-//** Padding around the thumbnail caption
-@thumbnail-caption-padding: 9px;
-
-
-//== Wells
-//
-//##
-
-@well-bg: @gray-lighter;
-@well-border: transparent;
-
-
-//== Badges
-//
-//##
-
-@badge-color: #fff;
-//** Linked badge text color on hover
-@badge-link-hover-color: #fff;
-@badge-bg: @brand-primary;
-
-//** Badge text color in active nav link
-@badge-active-color: @brand-primary;
-//** Badge background color in active nav link
-@badge-active-bg: #fff;
-
-@badge-font-weight: bold;
-@badge-line-height: 1;
-@badge-border-radius: 10px;
-
-
-//== Breadcrumbs
-//
-//##
-
-@breadcrumb-padding-vertical: 8px;
-@breadcrumb-padding-horizontal: 15px;
-//** Breadcrumb background color
-@breadcrumb-bg: @gray-lighter;
-//** Breadcrumb text color
-@breadcrumb-color: #ccc;
-//** Text color of current page in the breadcrumb
-@breadcrumb-active-color: @gray;
-//** Textual separator for between breadcrumb elements
-@breadcrumb-separator: "/";
-
-
-//== Carousel
-//
-//##
-
-@carousel-text-shadow: 0 1px 2px rgba(0,0,0,.6);
-
-@carousel-control-color: #fff;
-@carousel-control-width: 15%;
-@carousel-control-opacity: .5;
-@carousel-control-font-size: 20px;
-
-@carousel-indicator-active-bg: #fff;
-@carousel-indicator-border-color: #fff;
-
-@carousel-caption-color: #fff;
-
-
-//== Close
-//
-//##
-
-@close-font-weight: bold;
-@close-color: #000;
-@close-text-shadow: none;
-
-
-//== Code
-//
-//##
-
-@code-color: #c7254e;
-@code-bg: #f9f2f4;
-
-@kbd-color: #fff;
-@kbd-bg: #333;
-
-@pre-bg: @gray-lighter;
-@pre-color: @gray-dark;
-@pre-border-color: #ccc;
-@pre-scrollable-max-height: 340px;
-
-
-//== Type
-//
-//##
-
-//** Horizontal offset for forms and lists.
-@component-offset-horizontal: 180px;
-//** Text muted color
-@text-muted: @gray-light;
-//** Abbreviations and acronyms border color
-@abbr-border-color: @gray-light;
-//** Headings small color
-@headings-small-color: @gray-light;
-//** Blockquote small color
-@blockquote-small-color: @gray-light;
-//** Blockquote font size
-@blockquote-font-size: (@font-size-base * 1.25);
-//** Blockquote border color
-@blockquote-border-color: @gray-lighter;
-//** Page header border color
-@page-header-border-color: transparent;
-//** Width of horizontal description list titles
-@dl-horizontal-offset: @component-offset-horizontal;
-//** Horizontal line color.
-@hr-border: @gray-lighter;
-
-// Flatly 3.3.0
-// Bootswatch
-// -----------------------------------------------------
-
-@import url("https://fonts.googleapis.com/css?family=Lato:400,700,400italic");
-
-// Navbar =====================================================================
-
-.navbar {
- border-width: 0;
-
- &-default {
-
- .badge {
- background-color: #fff;
- color: @navbar-default-bg;
- }
- }
-
- &-inverse {
-
- .badge {
- background-color: #fff;
- color: @navbar-inverse-bg;
- }
- }
-
- &-brand {
- padding: 18.5px 15px 20.5px;
- }
-}
-
-// Buttons ====================================================================
-
-.btn:active {
- .box-shadow(none);
-}
-
-.btn-group.open .dropdown-toggle {
- .box-shadow(none);
-}
-
-// Typography =================================================================
-
-.text-primary,
-.text-primary:hover {
- color: @brand-primary;
-}
-
-.text-success,
-.text-success:hover {
- color: @brand-success;
-}
-
-.text-danger,
-.text-danger:hover {
- color: @brand-danger;
-}
-
-.text-warning,
-.text-warning:hover {
- color: @brand-warning;
-}
-
-.text-info,
-.text-info:hover {
- color: @brand-info;
-}
-
-// Tables =====================================================================
-
-table,
-.table {
-
- a:not(.btn) {
- text-decoration: underline;
- }
-
- .dropdown-menu a {
- text-decoration: none;
- }
-
- .success,
- .warning,
- .danger,
- .info {
- color: #fff;
-
- a {
- color: #fff;
- }
- }
-
- > thead > tr > th,
- > tbody > tr > th,
- > tfoot > tr > th,
- > thead > tr > td,
- > tbody > tr > td,
- > tfoot > tr > td {
- border: none;
- }
-
- &-bordered > thead > tr > th,
- &-bordered > tbody > tr > th,
- &-bordered > tfoot > tr > th,
- &-bordered > thead > tr > td,
- &-bordered > tbody > tr > td,
- &-bordered > tfoot > tr > td {
- border: 1px solid @table-border-color;
- }
-}
-
-// Forms ======================================================================
-
-.form-control,
-input, {
- border-width: 2px;
- .box-shadow(none);
-
- &:focus {
- .box-shadow(none);
- }
-}
-
-.has-warning {
- .help-block,
- .control-label,
- .radio,
- .checkbox,
- .radio-inline,
- .checkbox-inline,
- .form-control-feedback {
- color: @brand-warning;
- }
-
- .form-control,
- .form-control:focus {
- border: 2px solid @brand-warning;
- }
-
- .input-group-addon {
- border-color: @brand-warning;
- }
-}
-
-.has-error {
- .help-block,
- .control-label,
- .radio,
- .checkbox,
- .radio-inline,
- .checkbox-inline,
- .form-control-feedback {
- color: @brand-danger;
- }
-
- .form-control,
- .form-control:focus {
- border: 2px solid @brand-danger;
- }
-
- .input-group-addon {
- border-color: @brand-danger;
- }
-}
-
-.has-success {
- .help-block,
- .control-label,
- .radio,
- .checkbox,
- .radio-inline,
- .checkbox-inline,
- .form-control-feedback {
- color: @brand-success;
- }
-
- .form-control,
- .form-control:focus {
- border: 2px solid @brand-success;
- }
-
- .input-group-addon {
- border-color: @brand-success;
- }
-}
-
-// Navs =======================================================================
-
-.nav {
- .open > a,
- .open > a:hover,
- .open > a:focus {
- border-color: transparent;
- }
-}
-
-.pager {
- a,
- a:hover {
- color: #fff;
- }
-
- .disabled {
- &>a,
- &>a:hover,
- &>a:focus,
- &>span {
- background-color: @pagination-disabled-bg;
- }
- }
-}
-
-// Indicators =================================================================
-
-.close {
- color: #fff;
- text-decoration: none;
- opacity: 0.4;
-
- &:hover,
- &:focus {
- color: #fff;
- opacity: 1;
- }
-}
-
-.alert {
-
- .alert-link {
- color: #fff;
- text-decoration: underline;
- }
-}
-
-// Progress bars ==============================================================
-
-.progress {
- height: 10px;
- .box-shadow(none);
- .progress-bar {
- font-size: 10px;
- line-height: 10px;
- }
-}
-
-// Containers =================================================================
-
-.well {
- .box-shadow(none);
-}
-
-a.list-group-item {
-
- &.active,
- &.active:hover,
- &.active:focus {
- border-color: @list-group-border;
- }
-
- &-success {
- &.active {
- background-color: @state-success-bg;
- }
-
- &.active:hover,
- &.active:focus {
- background-color: darken(@state-success-bg, 5%);
- }
- }
-
- &-warning {
- &.active {
- background-color: @state-warning-bg;
- }
-
- &.active:hover,
- &.active:focus {
- background-color: darken(@state-warning-bg, 5%);
- }
- }
-
- &-danger {
- &.active {
- background-color: @state-danger-bg;
- }
-
- &.active:hover,
- &.active:focus {
- background-color: darken(@state-danger-bg, 5%);
- }
- }
-}
-
-.panel {
- &-default {
- .close {
- color: @text-color;
- }
- }
-}
-
-.modal {
- .close {
- color: @text-color;
- }
-}
-
-.popover {
- color: @text-color;
-}
diff --git a/public/css/themes/modern.less b/public/css/themes/modern.less
deleted file mode 100644
index f9e6d8b25f..0000000000
--- a/public/css/themes/modern.less
+++ /dev/null
@@ -1,151 +0,0 @@
-@import url("http://fonts.googleapis.com/css?family=Montserrat:400,700");
-@import url("http://fonts.googleapis.com/css?family=Raleway:400,300");
-
-// Colors
-// -------------------------
-
-@gray-lighter: #f5f5f5;
-@gray-light: #e0e0e0;
-@gray: #737373;
-@gray-dark: #404040;
-@gray-darker: #121212;
-
-@brand-primary: #2ac5ee;
-@brand-success: #0f9d58;
-@brand-warning: #f4b400;
-@brand-danger: #d80017;
-@brand-info: #5bc0dd;
-
-// Footer
-// -------------------------
-
-footer {
- color: #fff;
- background-color: @gray-darker;
-
- a:hover {
- color: #fff;
- }
-}
-
-// Typography
-// -------------------------
-
-@font-size-base: 13px;
-@font-family-base: 'Montserrat', sans-serif;
-@headings-font-family: 'Montserrat', sans-serif;
-@headings-font-weight: 700;
-@text-color: @gray-darker;
-@link-color: @brand-primary;
-@link-hover-color: @gray-darker;
-
-a {
- transition: all .4s cubic-bezier(.24,.45,.46,.92);
-
- &:hover {
- text-decoration: none;
- }
-}
-
-ul,
-p {
- font-family: 'Raleway', sans-serif;
- font-size: 14px;
- font-weight: 300;
-}
-
-.text-danger {
- color: @brand-danger;
-}
-
-// Dropdowns
-// -------------------------
-
-@dropdown-link-color: @gray-darker;
-
-.dropdown-menu > li > a {
- font-weight: 300;
-}
-
-// Buttons
-// -------------------------
-
-@btn-default-bg: @gray-lighter;
-@btn-default-color: @gray-darker;
-
-.btn {
- padding: 10px 16px;
- border: 0;
- border-radius: 3px;
- transition: all .4s cubic-bezier(.24,.45,.46,.92);
-
- &:hover {
- color: #fff;
- background-color: @gray-darker;
- }
-}
-
-.btn-social {
- padding: 10px 50px;
-
- :first-child {
- width: 38px;
- line-height: 38px;
- }
-}
-
-.btn-link {
-
- &:hover {
- color: @gray-darker;
- text-decoration: none;
- background-color: transparent;
- }
-}
-
-// Forms
-// -------------------------
-
-@input-border-radius: 2px;
-@input-border-focus: #999;
-@input-border: #f0f0f0;
-@input-color: #444;
-@input-color-placeholder: #999;
-@input-height-base: 44px;
-
-// Form states and alerts
-// -------------------------
-
-@state-success-bg: @brand-success;
-@state-info-bg: @brand-primary;
-@state-warning-bg: @brand-warning;
-@state-danger-bg: @brand-danger;
-
-.alert {
- font-family: 'Raleway', sans-serif;
- color: #fff;
-}
-
-// Navbar
-// -------------------------
-
-@navbar-height: 50px;
-@navbar-default-bg: rgba(255,255,255,0.95);
-@navbar-default-link-color: @gray-darker;
-@navbar-default-link-active-color: @brand-primary;
-@navbar-default-link-active-bg: transparent;
-@navbar-default-link-hover-color: @brand-primary;
-@navbar-default-link-hover-bg: transparent;
-@navbar-default-brand-color: @gray-darker;
-@navbar-default-brand-hover-color: @brand-primary;
-
-.navbar-default {
- border: 0;
- box-shadow: 0 1px 5px rgba(0,0,0,.15);
-
- .navbar-nav {
- > li > a {
- transition: color .4s cubic-bezier(.24,.45,.46,.92);
- }
- }
-}
\ No newline at end of file
diff --git a/public/favicon.ico b/public/favicon.ico
index 3ec62dd50c..60054e1992 100644
Binary files a/public/favicon.ico and b/public/favicon.ico differ
diff --git a/public/favicons.html b/public/favicons.html
deleted file mode 100644
index ba348ed7db..0000000000
--- a/public/favicons.html
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/public/images/freeCodeCamp-puck.svg b/public/images/freeCodeCamp-puck.svg
new file mode 100644
index 0000000000..f2572ed38b
--- /dev/null
+++ b/public/images/freeCodeCamp-puck.svg
@@ -0,0 +1,37 @@
+
+
+
diff --git a/public/images/freecodecamp_logo.svg b/public/images/freecodecamp_logo.svg
deleted file mode 100644
index 2c24007979..0000000000
--- a/public/images/freecodecamp_logo.svg
+++ /dev/null
@@ -1,199 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/server/boot/authentication.js b/server/boot/authentication.js
index 100880e0a4..546bf6c755 100644
--- a/server/boot/authentication.js
+++ b/server/boot/authentication.js
@@ -29,25 +29,26 @@ module.exports = function enableAuthentication(app) {
const api = app.loopback.Router();
const { AuthToken, User } = app.models;
- router.get('/login', (req, res) => res.redirect(301, '/signin'));
- router.get('/logout', (req, res) => res.redirect(301, '/signout'));
- router.get('/signup', (req, res) => res.redirect(301, '/signin'));
- router.get('/email-signin', (req, res) => res.redirect(301, '/signin'));
+ router.get('/email-signin', (req, res) => res.redirect(301, '/login'));
+ router.get('/signin', (req, res) => res.redirect(301, '/signup'));
+ router.get('/signout', (req, res) => res.redirect(301, '/logout'));
- function getEmailSignin(req, res) {
+ function getLegacySignUp(req, res) {
if (isSignUpDisabled) {
return res.render('account/beta', {
title: 'New sign ups are disabled'
});
}
- return res.render('account/email-signin', {
+ return res.render('account/deprecated-signup', {
title: 'Sign in to freeCodeCamp using your Email Address'
});
}
+ router.get('/signup', ifUserRedirect, getLegacySignUp);
+ router.get('/login',
+ ifUserRedirect,
+ (req, res) => res.redirect(301, '/auth/auth0'));
- router.get('/signin', ifUserRedirect, getEmailSignin);
-
- router.get('/signout', (req, res) => {
+ router.get('/logout', (req, res) => {
req.logout();
res.redirect('/');
});
diff --git a/server/component-passport.js b/server/component-passport.js
index f08305a4f2..63104737ff 100644
--- a/server/component-passport.js
+++ b/server/component-passport.js
@@ -2,6 +2,7 @@ import passport from 'passport';
import { PassportConfigurator } from
'@freecodecamp/loopback-component-passport';
import passportProviders from './passport-providers';
+import url from 'url';
const passportOptions = {
emailOptional: true,
@@ -90,8 +91,58 @@ export default function setupPassport(app) {
configurator.init();
Object.keys(passportProviders).map(function(strategy) {
- var config = passportProviders[strategy];
+ let config = passportProviders[strategy];
config.session = config.session !== false;
+
+ // https://stackoverflow.com/q/37430452
+ let successRedirect = (req) => {
+ if (!!req && req.session && req.session.returnTo) {
+ let returnTo = req.session.returnTo;
+ delete req.session.returnTo;
+ return returnTo;
+ }
+ return config.successRedirect || '';
+ };
+
+ config.customCallback = !config.useCustomCallback
+ ? null
+ : (req, res, next) => {
+
+ passport.authenticate(
+ strategy,
+ { session: false },
+ (err, user) => {
+ if (err) {
+ return next(err);
+ }
+
+ if (!user) {
+ return res.redirect(config.failureRedirect);
+ }
+ let redirect = url.parse(successRedirect(req), true);
+
+ delete redirect.search;
+
+ req.flash(
+ 'success',
+ 'Success! You have signed in to your account. Happy Coding!'
+ );
+
+ // redirect.query = {
+ // /* eslint-disable camelcase */
+ // access_token: info.accessToken.id,
+ // /* eslint-enable camelcase */
+ // userId: user.id.toString()
+ // };
+
+ user.loginByRequest(req, res);
+
+ redirect = url.format(redirect);
+ return res.redirect(redirect);
+ }
+ )(req, res, next);
+ };
+
configurator.configureProvider(
strategy,
{
diff --git a/server/middlewares/error-reporter.js b/server/middlewares/error-reporter.js
index 5b3aaba86b..2eb8455e2c 100644
--- a/server/middlewares/error-reporter.js
+++ b/server/middlewares/error-reporter.js
@@ -10,7 +10,7 @@ const log = debug('fcc:middlewares:error-reporter');
const isOpbeatDisabled = !opbeat.appId;
export default function errrorReporter() {
- if (process.env.NODE_ENV !== 'production') {
+ if (process.env.NODE_ENV !== 'production' && process.env.ERROR_REPORTER) {
return (err, req, res, next) => {
if (isHandledError(err)) {
// log out user messages in development
diff --git a/server/passport-providers.js b/server/passport-providers.js
index 733d1b845c..bab270396b 100644
--- a/server/passport-providers.js
+++ b/server/passport-providers.js
@@ -1,5 +1,5 @@
const successRedirect = '/';
-const failureRedirect = '/signin';
+const failureRedirect = '/';
const linkSuccessRedirect = '/settings';
const linkFailureRedirect = '/settings';
@@ -165,5 +165,21 @@ export default {
'We\'ve updated your profile based ',
'on your your GitHub account.'
].join('')
+ },
+ 'auth0-login': {
+ provider: 'auth0',
+ module: 'passport-auth0',
+ clientID: process.env.AUTH0_CLIENT_ID,
+ clientSecret: process.env.AUTH0_CLIENT_SECRET,
+ domain: process.env.AUTH0_DOMAIN,
+ cookieDomain: 'freeCodeCamp.org',
+ callbackURL: '/auth/auth0/callback',
+ authPath: '/auth/auth0',
+ callbackPath: '/auth/auth0/callback',
+ useCustomCallback: true,
+ successRedirect: successRedirect,
+ failureRedirect: failureRedirect,
+ scope: ['openid email'],
+ failureFlash: true
}
};
diff --git a/server/views/account/deprecated-signin.jade b/server/views/account/deprecated-signin.jade
index 0cb67ef558..9d51f4f018 100644
--- a/server/views/account/deprecated-signin.jade
+++ b/server/views/account/deprecated-signin.jade
@@ -1,26 +1,34 @@
extends ../layout
block content
- .text-center
- h2 If you originally signed up using one of these methods, you can sign in and add your email address to your account:
- br
- a.btn.btn-lg.btn-block.btn-social.btn-github(href='/auth/github')
- i.fa.fa-github
- | Sign in with GitHub
- a.btn.btn-lg.btn-block.btn-social.btn-facebook(href='/auth/facebook')
- i.fa.fa-facebook
- | Sign in with Facebook
- a.btn.btn-lg.btn-block.btn-social.btn-google(href='/auth/google')
- i.fa.fa-google
- | Sign in with Google
- a.btn.btn-lg.btn-block.btn-social.btn-linkedin(href='/auth/linkedin')
- i.fa.fa-linkedin
- | Sign in with LinkedIn
- a.btn.btn-lg.btn-block.btn-social.btn-twitter(href='/auth/twitter')
- i.fa.fa-twitter
- | Sign in with Twitter
- br
- p
- a(href="/signin") Or click here to go back.
+ .container
+ .col-xs-12
+ .row
+ .text-center
+ h3 Sign in with one of these options if you used them as your original sign up methods :
+ br
+ a.btn.btn-lg.btn-block.btn-social.btn-github(href='/auth/github')
+ i.fa.fa-github
+ | Sign in with GitHub
+ a.btn.btn-lg.btn-block.btn-social.btn-facebook(href='/auth/facebook')
+ i.fa.fa-facebook
+ | Sign in with Facebook
+ a.btn.btn-lg.btn-block.btn-social.btn-google(href='/auth/google')
+ i.fa.fa-google
+ | Sign in with Google
+ a.btn.btn-lg.btn-block.btn-social.btn-linkedin(href='/auth/linkedin')
+ i.fa.fa-linkedin
+ | Sign in with LinkedIn
+ a.btn.btn-lg.btn-block.btn-social.btn-twitter(href='/auth/twitter')
+ i.fa.fa-twitter
+ | Sign in with Twitter
+ br
+ h3
+ | We are unable to create new accounts using these methods
+ h4 If you haven't updated your email with us, you should do that as soon as possible,
+ | after you login here, to avoid losing access to your account.
+ br
+ p
+ a(href="/signin") Or click here to go back.
script.
$(document).ready(function() {
diff --git a/server/views/account/deprecated-signup.jade b/server/views/account/deprecated-signup.jade
new file mode 100644
index 0000000000..b46594a565
--- /dev/null
+++ b/server/views/account/deprecated-signup.jade
@@ -0,0 +1,20 @@
+extends ../layout
+block content
+ .container
+ .col-xs-12
+ .row
+ .text-center
+ h2 Sign up (or sign in with your existing account)
+ br
+ br
+ br
+ a.btn.btn-lg.btn-primary(href='/auth/auth0')
+ | Continue with your email
+ .row
+ .text-center
+ br
+ br
+ br
+ br
+ a(href="/deprecated-signin")
+ | Continute with an old sign in method, that you used previously.
diff --git a/server/views/account/email-signin.jade b/server/views/account/email-signin.jade
deleted file mode 100644
index cf1fb37390..0000000000
--- a/server/views/account/email-signin.jade
+++ /dev/null
@@ -1,100 +0,0 @@
-extends ../layout
-block content
- .container
- .col-xs-12
- .row
- .col-sm-6.col-sm-offset-3.flashMessage.negative-30
- #flash-board.alert.fade.in(style='display: none;')
- button.close(type='button', data-dismiss='alert')
- span.ion-close-circled#flash-close
- #flash-content
- .row
- .text-center
- h2 Sign up (or sign in with your existing account)
- .button-spacer
- .col-sm-6.col-sm-offset-3
- form(method='POST', action='/passwordless-auth')
- input(type='hidden', name='_csrf', value=_csrf)
- .form-group
- input.input-lg.form-control(type='email', name='email', id='email', placeholder='Enter your email address', autofocus=true, required, oninvalid="this.setCustomValidity('Enter your email address')", oninput="setCustomValidity('')")
- .button-spacer
- button#magic-btn.btn.btn-primary.btn-lg.btn-block(type='submit')
- | Get a sign in link
- .row
- .col-sm-6.col-sm-offset-3
- br
- p.text-center
- br
- br
- a(href="/deprecated-signin") Try old sign in methods
-
- script.
- $(document).ready(function() {
- function disableMagicButton (isDisabled) {
- if (isDisabled) {
- $('#magic-btn')
- .prop('disabled', true)
- .html('OK - we\'re sending you an email. Open it and click sign in link.');
- } else {
- $('#magic-btn')
- .prop('disabled', true)
- .html('If you didn\'t get the email, check your spam folder, or reload the page to try again.');
- }
- }
-
- $('form').submit(function(event){
- event.preventDefault();
- $('#flash-board').hide();
- disableMagicButton(true);
- var $form = $(event.target);
- $.ajax({
- type : 'POST',
- url : $form.attr('action'),
- data : $form.serialize(),
- dataType : 'json',
- encode : true,
- xhrFields : { withCredentials: true }
- })
- .fail(error => {
- if (error.responseText){
- var data = JSON.parse(error.responseText);
- if(data.error && data.error.message) {
- $('#flash-content').html(data.error.message);
- $('#flash-board')
- .removeClass('alert-success')
- .addClass('alert-info')
- .slideDown(400)
- .delay(800)
- .fadeIn();
- disableMagicButton(false);
- }
- }
- })
- .done(data => {
- if(data && data.message) {
- var alertType = 'alert-';
- switch (data.type) {
- case 'errors': {
- alertType += 'danger';
- break
- }
- case 'success': {
- alertType += 'success';
- break
- }
- default: {
- alertType += 'info';
- }
- }
- $('#flash-content').html(data.message);
- $('#flash-board')
- .removeClass('alert-info alert-success alert-danger')
- .addClass(alertType)
- .slideDown(400)
- .delay(800)
- .fadeIn();
- disableMagicButton(false);
- }
- });
- });
- });