userin-form-gray-quail
v0.0.15
Published
Configurable JS form widget that uses the UserIn middleware to login to Apps using popular Identity Providers such as Facebook, Google, LinkedIn, GitHub, ...
Downloads
23
Readme
UserIn Form - Gray Quail ·
UserIn Form - Gray Quail is a configurable JS form widget that uses the UserIn middleware to login to Apps using the following popular Identity Providers:
- GitHub
This project uses vanilla JS and CSS. There are no dependencies, except for development. More about modifying this project to your own needs under the Customizing This Project To Your Own Needs section.
Table of Contents
Install
Add the CSS and the JS into your web page as follow:
<!DOCTYPE html>
<html>
<head>
<!-- Some HTML here... -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/userin-form-gray-quail/dist/style.min.css">
</head>
<body>
<div id="userin-form-modal"></div>
<!-- Some HTML here... -->
<script src="https://cdn.jsdelivr.net/npm/userin-form-gray-quail"></script>
<script type="text/javascript">
var loginForm = new UserInForm({
el: '#userin-form-modal',
usernamePassword: 'https://your-hosted-userin-domain/default/oauth2'
})
</script>
</body>
</html>
This example demonstrates the minimal configuration.
| Parameter | Field | Type | Description |
|-----------------------|-----------|-----------|-------------------------------------------------------------------------------|
| el
| OPTIONAL | String | CSS selector to the DOM under which the form is inserted. If not defined, the form is attached under the body |
| usernamePassword
| REQUIRED | String | URL of your UserIn auth endpoint (e.g., http://localhost:3000/default/oauth2) |
Configuration
Standard Config
The configuration above showcases the minimal settings. The following example demonstrates a configuration that is a bit more common:
var loginForm = new UserInForm({
el: 'some-css-dom-selector',
logo: "https://neap.co/img/neap_color_horizontal.png",
tagline: "Killer App",
blurb: "The adventure begins now",
usernamePassword: 'http://localhost:3000/default/oauth2',
facebook: 'http://localhost:3000/facebook/oauth2',
google: 'http://localhost:3000/google/oauth2',
terms: 'https://termsfeed.com/blog/saas-terms-use-privacy-policy/',
privacyPolicy: 'https://privacypolicies.com/blog/privacy-policy-saas/',
forgotPassword: 'https://neap.co',
redirectUrls: {
onSuccess: 'http://localhost:8080/success',
onError: 'http://localhost:8080/dev'
}
})
Parameters
| Parameter | Field | Type | Description |
|-----------------------|-----------|-----------|-------------------------------------------------------------------------------|
| el
| OPTIONAL | String | CSS selector to the DOM under which the form is inserted. If not defined, the form is attached under the body |
| logo
| OPTIONAL | String | URL of the logo that appears at the top of the form. |
| tagline
| OPTIONAL | String | Tagline that appears at the top of the form. |
| blurb
| OPTIONAL | String | Blurb that appears at the top of the form. |
| usernamePassword
| REQUIRED | String | URL of your UserIn auth endpoint (e.g., http://localhost:3000/default/oauth2) |
| facebook
| OPTIONAL | String | URL of your UserIn OAuth endpoint for Facebook (e.g., http://localhost:3000/facebook/oauth2) |
| google
| OPTIONAL | String | URL of your UserIn OAuth endpoint for Google (e.g., http://localhost:3000/google/oauth2) |
| terms
| OPTIONAL | String | URL to your terms and conditions web page. |
| privacyPolicy
| OPTIONAL | String | URL to your privacy policy web page. |
| forgotPassword
| OPTIONAL | String | URL to your forgot password web page. |
| redirectUrls
| OPTIONAL | Object | URLs used after successful or failed authentication. |
RECOMMENDATION: Use the URL where this form is hosted for the
redirectUrls.onError
. UserIn passes error messages in the query string and this form has been created to handled this format. When an error occurs, the details will be displayed in this form.
NOTE: The order in which the Identity Providers appear in the form can be modified by changing the order of their definitions. In the example above, putting Google before Facebook cna be done as follow:
{ google: 'http://localhost:3000/google/oauth2', facebook: 'http://localhost:3000/facebook/oauth2', }
Switching To Modal Mode
This example is very similar to the one above, but instead of using a static form, this configuration uses a modal:
<!DOCTYPE html>
<html>
<head>
<title>UserIn - Gray Quail</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/userin-form-gray-quail/dist/style.min.css">
</head>
<body>
<button id="login">Login</button>
<div id="main"></div>
<script src="https://cdn.jsdelivr.net/npm/userin-form-gray-quail"></script>
<script type="text/javascript">
var loginForm = new UserInForm({
el: '#main',
logo: "https://neap.co/img/neap_color_horizontal.png",
tagline: "Killer App",
blurb: "The adventure begins now",
usernamePassword: 'http://localhost:3000/default/oauth2',
facebook: 'http://localhost:3000/facebook/oauth2',
google: 'http://localhost:3000/google/oauth2',
terms: 'https://termsfeed.com/blog/saas-terms-use-privacy-policy/',
privacyPolicy: 'https://privacypolicies.com/blog/privacy-policy-saas/',
forgotPassword: 'https://neap.co',
redirectUrls: {
onSuccess: 'http://localhost:8080/success',
onError: 'http://localhost:8080/dev'
},
modal: {
animate: true
},
init: {
visible: false
}
})
document.getElementById('login').addEventListener('click', function() {
loginForm.show()
return false
})
</script>
</body>
</html>
Parameters
| Parameter | Field | Type | Description |
|-----------------------|-----------|-------------------|-----------------------------------------------------------------------|
| modal
| OPTIONAL | Boolean or Object | To toggle the modal mode, set this property to either true or a truthy object. |
| modal.animate
| OPTIONAL | Boolean | Default is false. When false, the modal appears immediately when it is opened. It also disappears immediately when it is closed. When set to true, opening and closing the form respectively fades in and out. |
| init
| OPTIONAL | Object | This object determines the form's behavior after it has loaded. |
| init.visible
| OPTIONAL | Boolean | Default is true. When true, the form appears automatically after it is loaded. When set to false, the form when it has loaded. It must be opened explicitely using the show()
api as demonstrated at the bottom of the example above. |
Other Configs
Changing The Default Form From Sign Up To Log In
Use the init
property as follow:
init: {
mode: 'login'
}
Configuring Tagline & Blurb For The Login and Sign Up Forms
Instead of using the tagline
and blurb
as previously:
tagline: "Killer App",
blurb: "The adventure begins now"
Use:
tagline: {
signup: "Killer App",
login: "Welcome Back"
},
blurb: {
signup: "The adventure begins now",
login: "Let's continue"
}
Full Parameters List
| Parameter | Field | Type | Description |
|-----------------------|-----------|-----------|-------------------------------------------------------------------------------|
| el
| OPTIONAL | String | CSS selector to the DOM under which the form is inserted. If not defined, the form is attached under the body |
| usernamePassword
| REQUIRED | String | URL of your UserIn auth endpoint (e.g., http://localhost:3000/default/oauth2) |
| logo
| OPTIONAL | String | URL of the logo that appears at the top of the form. |
| tagline
| OPTIONAL | String | Tagline that appears at the top of the form. |
| blurb
| OPTIONAL | String | Blurb that appears at the top of the form. |
| facebook
| OPTIONAL | String | URL of your UserIn OAuth endpoint for Facebook (e.g., http://localhost:3000/facebook/oauth2) |
| google
| OPTIONAL | String | URL of your UserIn OAuth endpoint for Google (e.g., http://localhost:3000/google/oauth2) |
| terms
| OPTIONAL | String | URL to your terms and conditions web page. |
| privacyPolicy
| OPTIONAL | String | URL to your privacy policy web page. |
| forgotPassword
| OPTIONAL | String | URL to your forgot password web page. |
| redirectUrls
| OPTIONAL | Object | URLs used after successfull or failed authentication. |
| redirectUrls.success
| OPTIONAL | String|Object | URL used after successfull authentication. If it is an object, then it must define 2 properties: login
and signup
. |
| redirectUrls.success.login
| REQUIRED | String| URL used after successfull authentication on the login form. |
| redirectUrls.success.signup
| REQUIRED | String| URL used after successfull authentication on the signup form. |
| redirectUrls.error
| OPTIONAL | String|Object | URL used after failed authentication. If it is an object, then it must define 2 properties: login
and signup
. |
| redirectUrls.error.login
| REQUIRED | String| URL used after failed authentication on the login form. |
| redirectUrls.error.signup
| REQUIRED | String| URL used after failed authentication on the signup form. |
| modal
| OPTIONAL | Boolean or Object | To toggle the modal mode, set this property to either true or a truthy object. |
| modal.animate
| OPTIONAL | Boolean | Default is false. When false, the modal appears immediately when it is opened. It also disappears immediately when it is closed. When set to true, opening and closing the form respectively fades in and out. |
| init
| OPTIONAL | Object | This object determines the form's behavior after it has loaded. |
| init.mode
| OPTIONAL | String | Default is 'signup'. With 'signup', the default form shown to the user when the widget appears is the signup form. When set to 'login', the first form shown to the user when the widget appears is the login form. |
| init.visible
| OPTIONAL | Boolean | Default is true. This configuration is only when the modal
property is truthy. When true, the form appears automatically after it is loaded. When set to false, the form when it has loaded. It must be opened explicitely using the show()
api as demonstrated at the bottom of the example above. |
How To
How To Control The Form With Query Parameters?
This UserIn Form supports configuration through URL query parameters. For example:
http://localhost:8080/dev?screen=login&redirect_url=https%3A%2F%2Fexample.com
This URI opens the form login
form instead of the default signup
. Upon successfull login, the redirect url is overidden by https://example.com.
It is also possible to pre-fill the form as explained in the next section.
The full supported list of params is:
|Parameter | Description |
|:--------------|:------------|
| screen
| Determines which form needs to be displayed. Possible values are: login
, signup
|
| redirect_url
| Determines where to redirect upon successfull authentication. |
| firstName
| Pre-fills the signup's first name field |
| lastName
| Pre-fills the signup's last name field |
| email
| Pre-fills both the signup and login email field |
How To Pre-Fill Form?
Pre-filling the UserIn Form is possible using query parameters. The following example shows an exhaustive case of all the parameters that can be used:
http://localhost:8080/dev?screen=login&firstName=Nic&lastName=Dao&email=nic%40neap.co
Where:
|Parameter | Description |
|:--------------|:------------|
| screen
| Determines which form needs to be displayed. Possible values are: login
, signup
|
| firstName
| Pre-fills the signup's first name field |
| lastName
| Pre-fills the signup's last name field |
| email
| Pre-fills both the signup and login email field |
This feature is what allows the next trick: How To Keep The Form Filled With The User Info After A Failed Login or Signup?.
How To Keep The Form Filled With The User Info After A Failed Login or Signup?
When the uses wrongly enter their password or username, they may be redirected back to the UserIn Form if you've setup the redirectUrls
property to do so. By default, the form restarts and all the previously filled up inputs are empty. If you want to preserve the previous inputs to avoid your users to be forced to re-enter their details again, you can configure your UserIn microservice to return your users' details in the query paramaters. As explained above, this pre-fills the form.
List Of Supported Identity Providers
This UserIn form widjet supports 5 different Identity Providers (IdPs) and the standard username/password form. To use any of those IdPs, your UserIn instance must have been configured to support them. To set up an IdP in UserIn, please refer to the documentation here.
Once configured in UserIn, each IdP should have an entry point similar to https://your-hosted-userin-domain/<idp-name>/oauth2
. Configuring this form with an IdP can then be achieved by modifying this UserInForm
input as follow:
new UserInForm({
// other configs...
usernamePassword: 'https://your-hosted-userin-domain/default/oauth2',
facebook: 'https://your-hosted-userin-domain/facebook/oauth2',
google: 'https://your-hosted-userin-domain/google/oauth2',
linkedin: 'https://your-hosted-userin-domain/linkedin/oauth2',
github: 'https://your-hosted-userin-domain/github/oauth2',
twitter: 'https://your-hosted-userin-domain/twitter/oauth2'
})
This config will enable all available IdPs in that order:
- GitHub
To change the order to, for example:
- GitHub
Simply change the input order as follow:
new UserInForm({
// other configs...
usernamePassword: 'https://your-hosted-userin-domain/default/oauth2',
twitter: 'https://your-hosted-userin-domain/twitter/oauth2',
github: 'https://your-hosted-userin-domain/github/oauth2',
linkedin: 'https://your-hosted-userin-domain/linkedin/oauth2',
google: 'https://your-hosted-userin-domain/google/oauth2',
facebook: 'https://your-hosted-userin-domain/facebook/oauth2'
})
Customizing This Project To Your Own Needs
This project aims to be modified by you so you can customize it beyond the out-of-the-box configurations we offer. There are 2 ways you can customize this project:
- Option 1 - Replace The CSS With Your Own (easiest): With this option, the form's functionalities fit all you needs, but the style does not. To solve this challenge, simply copy this form's CSS, and update it based on your specific needs.
- Option 2 - Clone This Project And Build Your Own Form: With this option, the functionalities of this form do not meet your requirements fully. Instead of recoding everything from scratch, you prefer to leverage our work and modify our code.
Option 1 - Replace The CSS With Your Own
The original CSS and its minified version are respectively hosted at:
- https://cdn.jsdelivr.net/npm/userin-form-gray-quail/dist/style.css
- https://cdn.jsdelivr.net/npm/userin-form-gray-quail/dist/style.min.css
Copy the unminified version, modify it, and use your version instead of ours.
Option 2 - Clone This Project And Build Your Own Form
Follow the next steps to build your own form using this project:
1. Clone/Fork This Project
Fork this repo, or clone it using:
git clone https://github.com/nicolasdao/userin-form-gray-quail.git
2. Install The Dev Dependencies & Run The Project
npm i
The only dependencies of this project are dev dependencies which can be described in a nutshell as:
- babel + webpack + uglifyjs: Used to compiled the source code written with ES6 to ES5.
- uglifycss: Used to compress the CSS.
- eslint: Used to lint the code.
- standard-version: Used to facilitate the version bumping and the CHANGELOG maintenance.
- express: Used to host a test server.
The source code itself does not use any dependencies. It is pure vanilla JS and vanilla CSS.
After installing all the dependencies, run the server:
npm start
This will host a demo page with a login button at http://localhost:8080/dev/.
INFO: The HTML page hosted at the above URL is the
index-dev.html
. Use this page during your test. Theindex-prod.html
is discussed later in step 4. Rebuild For Production Use.
3. Modify The Source Code To Fit Your Requirements
The source code is located under the src
folder. There are only 2 files:
- index.js: Contains the vanilla ES6 JS responsible to configure the widget.
- style.css: Contains the vanilla CSS responsible to styling the widget.
4. Rebuild For Production Use
Once you're done with all your code changes and you feel ready to deploy your code in production, follow the next steps:
- Lint the code to minimize the risk of silly mistakes:
npm run lint
. - Change the project name in the
package.json
touserin-form-<your code name>
. This is important if you're interested in having your form listed as an official UserIn form. If you're not interested, rename that package using whatever name you want. - Compile the code to support ES5 and minimize both the JS and CSS:
npm run build
. - Test your rebuilt widget using the prod endpoint:
npm start
- Browse to http://localhost:8080/prod/. This endpoint serves the
index-prod.html
page which is configured to serve the content compiled inside thedist
folder.
Deploy Your New Widget To NPM & JsDeliver CDN
Deploy your new UserIn form to NPM: npm publish
This command will automatically host your new widget for free using the https://www.jsdelivr.com/ CDN. Your code will be available at:
- Unminified JS: https://cdn.jsdelivr.net/npm/your-package-name@your-current-version/dist/index.js
- Minified JS: https://cdn.jsdelivr.net/npm/your-package-name@your-current-version/dist/index.min.js
- Unminified CSS: https://cdn.jsdelivr.net/npm/your-package-name@your-current-version/dist/style.css
- Minified JS: https://cdn.jsdelivr.net/npm/your-package-name@your-current-version/dist/style.min.css
Contribute
Though this project is designed to be forked and modified to your own custom needs, we also accepts pull requests.
This Is What We re Up To
We are Neap, an Australian Technology consultancy powering the startup ecosystem in Sydney. We simply love building Tech and also meeting new people, so don't hesitate to connect with us at https://neap.co.
Our other open-sourced projects:
GraphQL
- graphql-s2s: Add GraphQL Schema support for type inheritance, generic typing, metadata decoration. Transpile the enriched GraphQL string schema into the standard string schema understood by graphql.js and the Apollo server client.
- schemaglue: Naturally breaks down your monolithic graphql schema into bits and pieces and then glue them back together.
- graphql-authorize: Authorization middleware for graphql-serverless. Add inline authorization straight into your GraphQl schema to restrict access to certain fields based on your user's rights.
React & React Native
- react-native-game-engine: A lightweight game engine for react native.
- react-native-game-engine-handbook: A React Native app showcasing some examples using react-native-game-engine.
Authentication & Authorization
- userin: UserIn let's App engineers to implement custom login/register feature using Identity Providers (IdPs) such as Facebook, Google, Github.
General Purposes
- core-async: JS implementation of the Clojure core.async library aimed at implementing CSP (Concurrent Sequential Process) programming style. Designed to be used with the npm package 'co'.
- jwt-pwd: Tiny encryption helper to manage JWT tokens and encrypt and validate passwords using methods such as md5, sha1, sha256, sha512, ripemd160.
Google Cloud Platform
- google-cloud-bucket: Nodejs package to manage Google Cloud Buckets and perform CRUD operations against them.
- google-cloud-bigquery: Nodejs package to manage Google Cloud BigQuery datasets, and tables and perform CRUD operations against them.
- google-cloud-tasks: Nodejs package to push tasks to Google Cloud Tasks. Include pushing batches.
License
Copyright (c) 2017-2019, Neap Pty Ltd. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
- Neither the name of Neap Pty Ltd nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NEAP PTY LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.