endpoint-jan

1.1.0-rc1 • Public • Published

jwt-auth-node

JAN - Jwt Auth Node Is a project to simplify auth systems enough for everyday use. you npm install and add in the middleware

Written by kier to bring plan map auth to external projects

repo

docs

sponsor (endpoint.ca)

NPM Version

Usage

  1. add ssh key as deploy token to theis project
  2. endpoint-jan
  3. const jan = require('endpoint-jan') include jan
  4. create tables in pg and init pool
  5. jan.init(pool, {jwtSecret: 'hwtEncodingSecretDontLeak:)'})' init jan see docs but essentaly for jan.init
  6. app.get('/resource', jan.checkAuthenticated, (req,res)=>...) use jan (see other middleware or use jan.findUser

Background

The init function in JAN is responsible for setting up the entire implementation of JAN within a node server or express app. It requires the pg pool for planmap database to be passed in as the first parameter, along with various other optional options.

The options object can contain several properties, including jwtSecret, which is required and sets the secret for the users table so that users can be registered and their passwords can be verified. Other optional properties include loginRoute, which is the route for JAN's simple login form, cookieName, which sets the name for JAN's cookie, salt, which sets the bcrypt salt iterations, maxExpiry, which can enforce a maximum expiry time that cannot be overridden, and onlyUsers, which can be set to truthy to disable all other user tables.

If an express app is passed in through the options.app property, JAN routes will be automatically added to it. If options.email and options.nodemailer are passed in, JAN email functionality will be set up. Otherwise, a warning message will be logged.

After the init function has finished setting up all the necessary components, any initCallbacks that have been added will be called with the pool as the parameter.

Here's an example usage of the init function:

let pool = new Pool({/* pg db config */});
let app = express();
jan.init(pool, {jwtSecret: "dontLeakMeFoo"});

In this example, init is called with the pool object and the app object, which is an instance of express. This sets up JAN within the express app, allowing for easy user authentication and management.

JWT - JSON web tokens is a why of encoding data such that when someone steals they can't decode it and you can validate that it is not tampered with when you receive it later Jan is a Node.js authentication library that provides a simple and secure way to handle user authentication and authorization in your applications. With Jan, you can set up a compatible user table in your database and start authorizing clients in no time.

To use Jan, you need to initialize it and pass in the database pool and other implementation-specific options. The required jwtSecret option is the secret for your users' table, which is used to register users and verify their passwords. Additionally, you can set options such as loginRoute, cookieName, and maxExpiry to customize your implementation.

Jan uses bcrypt to securely store authentication information in a PostgreSQL users table. If you need more functionality, such as managing groups and clients, you can also use the Groups, Clients, and Table.js classes provided by Jan.

One potential future addition to Jan is support for OAuth servers, which would enable more generic implementations and simplify some processes. Additionally, a more traditional approach where an authentication server talks to many other servers could be implemented.

Overall, Jan provides a simple and standardized way to handle user authentication and authorization in Node.js applications.

docs

include

const jan = require('jan')

initialize, note you need to have the node pg.Pool and secret already

jan.init(pool, {jwtSecret: 'jwtSecret-changn_me23b2kj42hg34jkh234'})

login page

app.use('/', jan.getRouter())

private

app.get('/private', jan.checkAuthenticated, (req, res => {
    res.send('private page')
}))

public

app.get('/public', (req, res => {
    res.send('public page')
}))

middleware

jan.checkAuthenticated // redirects to login if no jwt is present in params/body Authorization Header or jan-cookie
jan.checkAuthenticatedAPI // sends json 401 rather then redirection
//both above set req.user 
jan.findUser // gets a user but does nothing

jan.checkGroup('group1', 'group2') // returns middleware whitch requires user to be in group1 and group2

jan.login // checks for username/email or id and password in params and body if present atempts to login
// if succesful sends {success:ture, msg, token, user, exp} otherwise {success:false, msg, debug}

//planed (not implemented yet)
jan.checkGroup(group_name) // will check if user is in a group
jan.newCustomer // under dev 
jan.invalidate
jan.lockUser
jan.checkClient(client_name)// might work untested

Full docs https://vgeo1.gitlab.io/jwt-auth-node/

git clone ssh://gitlab.com/vgeo1/jwt-auth-node.git
npm run docs

Using Email

add the fallowing config to your env.js

Example frontend

<!--here is an example of how you could implement an HTML form and CSS styles for the jan.initForm() function:-->
<script src="/node_modules/jan/janBrowser.js"></script>
<!-- login form -->
<form id="login-form">
    <label for="username">Username:</label><br>
    <input type="text" id="username" name="username"><br>
    <label for="password">Password:</label><br>
    <input type="password" id="password" name="password"><br><br>
    <button type="button" id="submit-button">Log in</button>
</form>

<style>
    /* form styles */
    form {
        display: flex;
        flex-direction: column;
        width: 300px;
    }

    label {
        font-weight: bold;
        margin-bottom: 5px;
    }

    input {
        margin-bottom: 15px;
        padding: 5px;
    }

    button {
        background-color: #4CAF50;
        border: none;
        color: white;
        padding: 10px;
        font-size: 16px;
        cursor: pointer;
    }


</style>
// You can then use the jan.initForm() function to set up the form for login like this:
jan.initForm('#username', '#password', '#submit-button');

Table sql for new db setup

GIVE ME SOME SQL
create table users
(
	id uuid default uuid_generate_v4() not null
		constraint node_users_pkey
			primary key,
	fname varchar(30) not null,
	lname varchar(30) not null,
	username varchar(30) not null
		constraint username_key
			unique,
	email varchar(128) not null
		constraint node_users_email_key
			unique,
	password varchar(128),
	photo varchar,
	last_login timestamp,
	json json default '{   "notificationPreferences": [     "releaseNotes",     "systemOutages",     "dataSharing"   ] }'::json,
	updatedatabaseusers boolean default false,
	remarks varchar(255),
	createdby varchar(100) default "current_user"() not null,
	createddate timestamp default ('now'::text)::timestamp without time zone not null,
	lastmodified timestamp default ('now'::text)::timestamp without time zone not null,
	modifiedby varchar(100) default "current_user"() not null,
	eula json default '{}'::json not null
);

comment on column users.id is 'the unigue ID used for relationships with other tables.';

comment on column users.fname is 'users last name';

comment on column users.lname is 'users last name';

comment on column users.username is 'users user name. Generaly first initial, last name such as vgreen for Vera Green';

comment on column users.email is 'users email address';

comment on column users.password is 'users hashed password where hash is controled from nodeJS';

comment on column users.last_login is 'The last time the user logged in. ';

comment on column users.updatedatabaseusers is 'If true, the next time the user logs in their user is updated on the databases the user requires access to.';

comment on column users.createdby is 'Standard editor tracing field populated by the editor_tracking trigger: the name of the user who created the record.';

comment on column users.createddate is 'Standard editor tracing populated by the editor_tracking trigger: the date the record was created.';

comment on column users.lastmodified is 'Standard editor tracing populated by the editor_tracking trigger: the date the record was last modified.';

comment on column users.modifiedby is 'Standard editor tracing populated by the editor_tracking trigger: the user who last modified the record.';

comment on column users.eula is 'End User License Agreement (EULA) metadata';

alter table users owner to geoadmin;

create trigger editor_tracking
	before update
	on users
	for each row
	execute procedure vgeo_update_editor_tracking();

grant delete, insert, references, select, trigger, truncate, update on users to public;

permision

https://gitlab.com/vgeo1/hawk-data-terminal/-/issues/8

CREATE ROLE r_planmap_view WITH
  NOLOGIN
  NOSUPERUSER
  INHERIT
  NOCREATEDB
  NOCREATEROLE
  NOREPLICATION;
  comment on ROLE r_planmap_view is 'a group role which can view and select from all planmap admin tables';
  
  CREATE ROLE r_planmap_edit WITH
  NOLOGIN
  NOSUPERUSER
  INHERIT
  NOCREATEDB
  NOCREATEROLE
  NOREPLICATION;
  comment ON ROLE r_planmap_edit is 'a group role which can edit all planmap admin tables';
  GRANT r_planmap_view TO r_planmap_edit;
  
  
    CREATE ROLE r_planmap_jen_auth WITH
  NOLOGIN
  NOSUPERUSER
  INHERIT
  NOCREATEDB
  NOCREATEROLE
  NOREPLICATION;
comment on ROLE r_planmap_jan_authis 'a group role which can authenticate against plan-map using jwt auth node';

add a user

CREATE ROLE jan_carbon WITH
  LOGIN
  NOSUPERUSER
  INHERIT
  NOCREATEDB
  NOCREATEROLE
  NOREPLICATION;

GRANT r_planmap_jan_auth TO jan_carbon;

COMMENT ON ROLE jan_carbon IS 'user is used for jwt-auth-node for the carbon project authentication configuration. Vera knows the PW. DO NOT REMOVE, DO NOT RESET';

ALTER ROLE jan_carbon PASSWORD 'xxxxxx';

Package Sidebar

Install

npm i endpoint-jan

Weekly Downloads

2

Version

1.1.0-rc1

License

UNLICENCED

Unpacked Size

1.75 MB

Total Files

80

Last publish

Collaborators

  • syonfox