RDB2JS Authenticate

Credit Card module for the RdbHost JavaScript V2 library.
The library can be loaded with a script tag, like:

<script src="https://www.rdbhost.com/vendor/rdbhost/2.3/lib/js/util-bundle;rdbhost.js"></script>
<script src="https://www.rdbhost.com/vendor/rdbhost/2.3/lib/js/rdb2-authenticate.js"></script>

A more performant way is to include it in the LAB.JS config:

<script> var $L = $LAB.script('/vendor/rdbhost/2.3/lib/js/rdb2-authenticate.js')</script>

How to Use

To use the rdb2-authenticate module, you need to setup an account on each authentication providers you choose to use. Twitter, Facebook, and Google all support federated identity.

Have the client_key and client_secret data available from the setup.

The confirm_fedauth_login method should be called in the startup code for the app, so it runs when the page loads. It returns a promise that resolves if the page load is the final step of the user's login.

The authentication related functionality is in the Authenticate element of Rdbhost.

var liProm = Rdbhost.Authenticate.confirm_fedauth_login();

liProm.then(function(userData) {
    if (!userData)
		return;

    if (userData.status === 'loggedin') {
        app.user = userData.identifier;
        app.key = userData.key;
    }
    else
        throw new Error('login status: '+userData.status);
}
		

The fedauth_login method is called when the user indicates an intention to login.

$('twitter-login').click(function(e) {
    Rdbhost.Authenticate.fedauth_login('Twitter', window.origin);
    // this function never returns.
}
		

When the fedauth_login method is first exercised, it will interactively populate the server-side fedauth provider table through a web form. You will need the client_key and client_secret from your chosen Auth provider for this.

Demo

A working demo is at JsDemos

Supporting Files

If you write the authenticate functions into your JavaScript and test, the JavaScript module should create and populate all necessary tables and other resources interactively as you test. If you want to manually create them, here are the resource definitions:

--
-- Name: account_passwords; Type: TABLE; Schema: auth; Owner: s0000000014; Tablespace:
--

CREATE TABLE account_passwords (
    idx integer,
    password character varying(150)
);

ALTER TABLE auth.account_passwords OWNER TO <super>



--
-- Name: login_fails; Type: TABLE; Schema: auth; Owner: s0000000014; Tablespace:
--

CREATE TABLE login_fails (
    fromip inet NOT NULL,
    tstamp timestamp with time zone
);


ALTER TABLE auth.login_fails OWNER TO s0000000014;


--
-- Name: password_login(character varying, character varying, inet); Type: FUNCTION; Schema: auth; Owner: s0000000014
--

CREATE FUNCTION password_login(
				IN  _userid character varying,
				IN  _password character varying,
				IN  _ip inet,
				OUT identifier character varying,
				OUT key character varying)
		RETURNS SETOF record
LANGUAGE plpgsql AS $$

DECLARE t RECORD;
BEGIN
	DELETE FROM auth.login_fails WHERE tstamp < now() - '1 minute'::interval;
	SELECT 1 INTO t FROM
		(SELECT count(*) AS ct FROM auth.login_fails WHERE fromip = _ip) AS _ct
	 WHERE ct >= 5;

	IF FOUND THEN
		RAISE EXCEPTION 'rdb77';
	END IF;

	RETURN QUERY SELECT fa.identifier, fa.key FROM
				         auth.fedauth_accounts fa JOIN auth.account_passwords a ON a.idx=fa.idx
				  WHERE md5(_password) = a.password
				    AND fa.identifier = _userid AND fa.issuer = 'LocalPassword';

	IF NOT FOUND THEN
		INSERT INTO auth.login_fails (fromip, tstamp) VALUES(_ip, now());
	END IF;

	RETURN;
END; $$;


ALTER FUNCTION auth.password_login(_userid character varying, _password character varying, _ip inet, OUT identifier character varying, OUT key character varying)
				OWNER TO <super>


--
-- Name: register_with_email(character varying); Type: FUNCTION; Schema: auth; Owner: s0000000014
--

CREATE FUNCTION register_with_email(
				IN  _email character varying,
				OUT email character varying,
				OUT body text)
		RETURNS SETOF record
    LANGUAGE plpgsql AS $$

DECLARE  _passwd VARCHAR;
BEGIN
	_passwd = substring(md5(random()::text) FROM 1 FOR 8);
	INSERT INTO auth.fedauth_accounts (idx, issuer, identifier, profile, key)
				VALUES(DEFAULT, 'LocalPassword', _email, '{}',
				md5(random()::text) || md5(random()::text) || md5(random()::text) );

	INSERT INTO auth.account_passwords (idx, password)
				VALUES (currval('auth.fedauth_accounts_idx_seq'::regclass), md5(_passwd));

	RETURN QUERY SELECT f.identifier, replace(t.body, '{{passwd}}', _passwd) FROM auth.fedauth_accounts f
					JOIN lookup.templates t ON (t.name = 'welcome.tpl')
				  WHERE f.idx = currval('auth.fedauth_accounts_idx_seq'::regclass);

	RETURN;
END; $$;


ALTER FUNCTION auth.register_with_email(_email character varying, OUT email character varying, OUT body text)
				OWNER TO <super>

				

Relevant Blog Posts