npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

knock-knock-knock

v1.0.0

Published

An authorization framework!

Downloads

3

Readme

TOC

KKK abbr. knock-knock-knock

Description

An authorization framework!

Features

  • extremely lightweight
  • zero dependencies
  • compatible with express
  • RESTful design
  • easy use with openid and oauth 2.0
  • easy to customize

Install

  • yarn:
yarn add knock-knock

# install needed schemas
# yarn add knock-google-openid
# yarn add knock-jwt-schema
  • npm:
npm install knock-knock

# install needed schemas
# npm install knock-google-openid
# npm install knock-jwt-schema

Example

basic example

let express = require('express');
let app = express();

app.use(express.json());

const KKK = require('../');
const kkk = new KKK({});

const schemaForKKK=require('./test-schema');

kkk.enable('test',schemaForKKK ,true);

app.post('/login', kkk.knockLogin('test'), (req, res, next) => {
    res.send('okay');
});

module.exports = app;

a full example for google open-id login and jwt auth

let express = require('express');
let cookieParser = require('cookie-parser');
let app = express();

app.use(express.json());
app.use(cookieParser('yijiang'));
app.use(express.urlencoded({extended: false}));

const KKK = require('knock-knock-knock');
let kkk = new KKK();

let googleSchemaClass = require('knock-google-openid');
let jwtSchemaClass = require('knock-jwt-schema');

// openid discovery method
googleSchemaClass.discovery().then((googleSchema) => {
    kkk.enable('google', googleSchema);
    kkk.enable('jwt', new jwtSchemaClass({secret: 'top-secret'}));
}).catch((err) => {
    console.error(err);
});

// oauth request step
app.get('/login', kkk.oauthLogin('google', {
    authSession: true,
    authSchemaID: 'jwt'
}));

// oauth callback step
app.get('/oauthcallback', kkk.knockLogin('google'), (req, res) => {
    if (req.user) {
        res.send(req.user);
    }
});

// jwt authorization
app.get('/dashboard', kkk.knockAuth('jwt'), (req, res) => {
    if (req.user) {
        res.send(req.user);
    }
});


app.use(function (err, req, res, next) {
    //deal with KKK's error
    if (err instanceof KKK.UnauthorizedError) {
        console.error(err);
        res.status(err.status).send(err);
    } else {
        res.status(500).send('interal error');
    }
})

module.exports = app;

Custom Schemas

in KKK there is two types of schema: login and auth.

  • login schema used as login or authentication. use this to get a login method
app.post('/login', kkk.knockLogin('test'), (req, res, next) => {
    res.send('okay');
});
  • auth schema used as create/revoke session and authorization. use this to get a auth method
app.get('/dashboard', kkk.knockAuth(), (req, res, next) => {
    if (req.user) {
        res.send(req.user);
    }
});

here is an example: this example show how to implements a schema

module.exports = function () {
    //login schema must implement this
    this.knockLogin = this.login = async function (req, res) {
        //you should check the login request from req
        //and must set one of them:

        // req.user =...
        // or
        // req.unauthorizedError = new KnockKnock.unauthorizedError();
    };

    //auth schema must implement this
    this.knockAuth = this.auth = async function (req, res) {
        //you should verify a session here...
        //and must set one of them:

        // req.user =...
        // or
        // req.unauthorizedError = new KnockKnock.unauthorizedError();
    }

    //optional for auth schema
    this.createSession = async function (req, res) {
    }
    this.revoke = function (req, res) {
    }

    //optional for login schema
    this.oauthCallback = function (req, res) {
    }
    this.oauthLogin = function (req, res) {
    }

};

every function here has same signature: async func(req,res),so you can:

  • return a Promise
  • use req,res same as express
  • set req.user as user object if login/auth approved
  • set req.UnauthorizedError to a KKK.UnauthorizedError if login/auth fatal
  • get req.user to verify user info(e.g. query database) because KKK's login schema(e.g knock-password-schema) only check the request but not verify it.
  • get req.user._schemaID specified which schema created this user object

More Specific

this shows how KKK internal flow

kkk.knockLogin
    =>(internal)loginSchema.knockLogin
    =>(internal)user `verify` function
    =>(internal)authSchema.createSession
kkk.knockAuth
    =>(internal)authSchema.knockAuth
    =>(internal)user `verify` function

so you have to:

  • set verify option if you want to verify request when you call kkk.knockLogin/kkk.knockAuth
  • specify createSession option if you want to create session otherwise it going to be one time authentication/authorization

Interface

  • call kkk.knockLogin(schema) and kkk.knockAuth(schema) is the most common way.
  • if you omit the schema option, kkk will try to refer it from client request:
_getParamFromReq(req, param) {
return req.params[param] || req.query[param] || req.cookies[param] || req.body[param];
}
  • kkk has shortcuts to directly get schema's methods, so after that you are able to pass it to express: you are able to use these shortcuts to get schema's method
//for login-schemas
kkk.login('test-schema');
kkk.oauthCallback('test-schema');
kkk.oauthLogin('test-schema');

//for auth-schemas
kkk.auth('test-schema');
kkk.revoke('test-schema')

options

verify

set verify will be called after kkk.knockLogin is called

kkk.knockLogin(
    'schema',
    {
        verify: async (req, res) => {
            return await database.query(req.user);
        }
    }
)

//or set globally...
kkk.option.globalLoginVerify = async (req, res) => {
    //...
}

kkk option

  • globalLoginVerify:the global login verify function
  • globalAuthVerify:the global auth verify function
  • throwUnauthorizedError:should throw error when unauthorized-error occurs otherwise kkk just only set req.unauthorizedError

API

Classes

Functions

Interfaces

schemaInterface

Kind: global interface
Ee: ./doc/examples/all-schema.js

schemaInterface.interface

a schema must implement one of the interface's methods

Kind: static interface of schemaInterface

interface.knockLogin(req, res)

must implement for login-schema.

Kind: static method of interface
Ee: ./doc/examples/login-schema.js

| Param | Type | Description | | --- | --- | --- | | req | Object | req.user should be set if user authorized or req.unauthorizedError should be set if error | | res | Object | same like express |

interface.knockAuth(req, res)

must implement for auth schema.

Kind: static method of interface
Ee: ./doc/examples/auth-schema.js

| Param | Type | Description | | --- | --- | --- | | req | Object | req.user should be set if user authorized or req.unauthorizedError should be set if error | | res | Object | same like express |

schemaInterface.loginOptional

if the schema implemented this interface , it is able to use [schemaFunctions] to call this function in schema

Kind: static interface of schemaInterface

loginOptional.login(req, res)

Kind: static method of loginOptional

| Param | Type | Description | | --- | --- | --- | | req | Object | req.user should be set if user authorized or req.unauthorizedError should be set if error | | res | Object | same like express |

loginOptional.oauthLogin(req, res)

Kind: static method of loginOptional

| Param | Type | Description | | --- | --- | --- | | req | Object | req.user should be set if user authorized or req.unauthorizedError should be set if error | | res | Object | same like express |

loginOptional.oauthCallback(req, res)

Kind: static method of loginOptional

| Param | Type | Description | | --- | --- | --- | | req | Object | req.user should be set if user authorized or req.unauthorizedError should be set if error | | res | Object | same like express |

schemaInterface.authOptional

if the schema implemented this interface , it is able to use [schemaFunctions] to call this function in schema

Kind: static interface of schemaInterface

authOptional.createSession(req, res)

Kind: static method of authOptional

| Param | Type | Description | | --- | --- | --- | | req | Object | req.user should be set if user authorized or req.unauthorizedError should be set if error | | res | Object | same like express |

authOptional.auth(req, res)

Kind: static method of authOptional

| Param | Type | Description | | --- | --- | --- | | req | Object | req.user should be set if user authorized or req.unauthorizedError should be set if error | | res | Object | same like express |

authOptional.revoke(req, res)

Kind: static method of authOptional

| Param | Type | Description | | --- | --- | --- | | req | Object | req.user should be set if user authorized or req.unauthorizedError should be set if error | | res | Object | same like express |

UnauthorizedError ⇐ Error

A Unauthorized Error

Kind: global class
Extends: Error

unauthorizedError.schema

Kind: instance property of UnauthorizedError

unauthorizedError.rawError

Kind: instance property of UnauthorizedError

KnockKnockKnock

knock-knock-knock main class

Kind: global class
Ee: ./doc/examples/newKKK.js

new KnockKnockKnock([option])

| Param | Type | | --- | --- | | [option] | Option |

knockKnockKnock.valid ⇒ boolean

check able to work available to work. it won't return true until least one login-schema are enabled

Kind: instance property of KnockKnockKnock

knockKnockKnock.enable(id, schema, setDefault)

enable a schema knock-knock-knock won't work until at least one login schema is enabled

Kind: instance method of KnockKnockKnock

| Param | Type | Default | Description | | --- | --- | --- | --- | | id | string | | schama id | | schema | schemaInterface | | schema | | setDefault | boolean | false | default use the schema if user won't specify a schema id |

Example

kkk.enable('test',schemaForKKK ,true);

knockKnockKnock.disable(id)

disable a schema

Kind: instance method of KnockKnockKnock

| Param | Type | Description | | --- | --- | --- | | id | string | schema id |

Example

kkk.disable('test');

knockKnockKnock.lazy(router)

Kind: instance method of KnockKnockKnock
Todo

  • [ ] implement this

| Param | | --- | | router |

knockKnockKnock.knockLogin([id], [option])

authenticate a request

Kind: instance method of KnockKnockKnock
Ee: ./doc/examples/knockLogin.js

| Param | Type | Default | Description | | --- | --- | --- | --- | | [id] | string | null | schema id | | [option] | actionOptions | {} | |

knockKnockKnock.knockAuth([id], [option])

authorize a request

Kind: instance method of KnockKnockKnock
Ee: ./doc/examples/knockAuth.js

| Param | Type | Default | Description | | --- | --- | --- | --- | | [id] | string | null | schema id | | [option] | actionOptions | {} | |

knockKnockKnock.[schemaFunctions](id, options)

return the functions from schema who implemented the interface loginOptional and authOptional

e.g if a schema which implements oauthLogin it could call knockKnockKnock.oauthLogin(id,option)

Kind: instance method of KnockKnockKnock
Ee: ./doc/examples/KKKLazy.js

| Param | Type | Description | | --- | --- | --- | | id | string | schema id enable | | options | actionOptions | |

KnockKnockKnock~Option

Kind: inner typedef of KnockKnockKnock
Properties

| Name | Type | Default | Description | | --- | --- | --- | --- | | [globalLoginVerify] | userVerifyFunction | | the global login verify function | | [globalAuthVerify] | userVerifyFunction | | the global auth verify function | | [throwUnauthorizedError] | boolean | true | should throw error when unauthorized-error occurs otherwise kkk just only set req.unauthorizedError |

KnockKnockKnock~actionOptions

Kind: inner typedef of KnockKnockKnock
Properties

| Name | Type | Default | Description | | --- | --- | --- | --- | | verify | userVerifyFunction | | verify function for current user object in req.user | | [authSession] | boolean | true | should invoke authSchema to create session after login | | authSchemaID | string | undefined | | auth-schema id to create session after login. undefined to use default schema |

userVerifyFunction(req, res)

Kind: global function
Ee: ./doc/examples/kkkverify.js

| Param | Type | Description | | --- | --- | --- | | req | Object | req.user should be set if user authorized or req.unauthorizedError should be set if error | | res | Object | same like express |

License

MIT