A modular authentication library for Deno.

Overview

Bedrock

drawing

A fully modular authentication library for Deno that intends to be the Bedrock of your application's authentication/session control. Bedrock provides authentication (Local + MFA, OAuth), and session handling middleware as well as conditional access controls to restrict access to your routes as defined by your application's requirements.

Check our website here for additional information and documentation!

Importing Bedrock

import { init } from 'https://deno.land/x/bedrock/mod.ts'

Implementation

Choose your desired strategy or strategies.

Bedrock offers several ways to provide multi-factor authentication through a local authentication strategy. These include TOTP through an authentication app, SMS, and Email. Additionally, we have abstracted away the process of implementing these six popular OAuth providers.

  • Discord
  • Facebook
  • Github
  • Google
  • LinkedIn
  • Twitter

Local Authentication Strategy

Define your parameters

Implementing your choice of strategies will require some variance in your parameters object. Visit our documentation for more information about which parameters you will need for your desired implementation.

const params: LocalAuthParams = {  
  checkCreds : dbController.checkCreds,
  mfaType: 'Token',
  getSecret: dbController.getSecret,
};

Initiate Bedrock

Initiate a Bedrock class object passing in params.

const Bedrock = init(params);

Implant Bedrock middleware into your routes

// Verification of username/password and creation of session
MFARouter.post('/login', Bedrock.localLogin, (ctx: Context) => {
  if(ctx.state.localVerified){
    //inside this if statement means user is locally authenticated with username/password  
    if(ctx.state.hasSecret === false){
      //inside this if statement means user is locally authenticated 
      //but does not have a stored secret
      ctx.response.body = {
        successful: true;
        mfaRequired: ctx.state.mfaRequired; //false
      }
  } else{
      //inside this else statement means user is locally authenticated and with a secret, 
      //to be redirected to verify MFA
      ctx.response.body = {
      successful: true,
      mfaRequired: ctx.state.mfaRequired; //true
    };
    ctx.response.status = 200;
  } else{
      //inside this else statement means user authentication with username/password failed
      ctx.response.body = {
        successful: false
      }
      ctx.response.status = 401;
  }
  return;

// Verification of MFA token code, if enabled
MFARouter.post('/checkMFA', Bedrock.checkMFA, (ctx: Context) => {
  console.log('Successfully verified MFA code');
  ctx.response.redirect('/secret');
  return;
});

// Secret route with session verification middleware
MFARouter.get('/secret', Bedrock.verifyAuth, (ctx: Context) => {
  console.log('Secret obtained!');
  ctx.response.body = 'Secret obtained!';
  ctx.response.status = 200;
  return;
});

// Route to log user out of server session
MFARouter.get('/signout', Bedrock.signOut, (ctx: Context) => {
  console.log('Successfully signed out');
  ctx.response.body = 'Successfully signed out';
  ctx.response.status = 200;
  return;
});

OAuth 2.0 Strategy

All OAuth providers require a client_id, client_secret, and redirect_uri. Additionally, Bedrock requires the developer to define scope for an added level of secruity. However, each OAuth provider publishes an extensive list of their supported scopes and they largely differ from each other. Please see our documentation for more information about scopes for specific OAuth providers.

Define your parameters

const params: OAuthParams = {
  provider: 'Github',
  client_id: Deno.env.get('CLIENT_ID')!,
  client_secret: Deno.env.get('CLIENT_SECRET')!,
  redirect_uri: Deno.env.get('AUTH_CALLBACK_URL')!,
  scope: 'read:user',
};

Initiate a Bedrock class

const Bedrock = init(params);

Implant Bedrock middleware into your routes

// Route to redirect user to OAuth provider's login site
OAuthRouter.get('/OAuth', Bedrock.sendRedirect);

// Route to retrieve access token and create user session
OAuthRouter.get('/OAuth/github', Bedrock.getToken, (ctx: Context) => {
  console.log('Successfully logged in via OAuth');
  ctx.response.redirect('/secret');
  return;
});

// Secret route with verification middleware
OAuthRouter.get('/secret', Bedrock.verifyAuth, (ctx: Context) => {
  console.log('Secret obtained!');
  ctx.response.body = 'Secret obtained!';
  ctx.response.status = 200;
  return;
});

// Route to log user out of OAuth and server session
OAuthRouter.get('/signout', Bedrock.signOut, (ctx: Context) => {
  console.log('Successfully signed out');
  ctx.response.redirect('/home');
  return;
});

How Bedrock is built

  • The timed one time password (TOTP) algorithm used in Bedrock follows the standard outlined in the IETF RFC 6238.
  • The SMS verification is provided through use of the Twilio API.
  • The email verification is provided through deno-mailer

How to Build Upon Bedrock

How to contribute...

  • The first way to contribute is by giving us feedback with context about your use case. The will help us determine where we can improve for future builds.
  • Other ways to contribute would be to contact us or open issues on this repo. If neither of those options work for you, email us at [email protected]

Authors

v1.0.3

  • Revision on auth logic for MFA
  • Updated additional variables to maintain camelCase consistency

v1.0.2

  • Removed debugging information from Twilio class
  • Changed mfa_type to mfaType to maintain camelCase consistency

v1.0.1

  • Added additional Local Authentication MFA option of e-mail (via deno-mailer)
  • Added additional OAuth strategies, including Discord, Facebook, LinkedIn, and Twitter

v1.0.0

Initial release supporting the following authentication strategies:

  • Local Authentication, with optional MFA options
    • TOTP code (generated by popular apps such as Google and Microsoft Authenticator)
    • SMS code (Via Twilio)
  • OAuth
    • Github
    • Google

Built on top of the Oak library and intended to be used as middleware in routes.

Session management handled by oak_sessions

You might also like...

A command-line tool to manage Deno scripts installed via deno install

🏞️ nublar nublar is a command-line tool to manage your scripts installed via deno install. 🛳️ Installation deno install --allow-read --allow-write -

Dec 26, 2022

A lightweight, fully-featured, modular, typescript-compatible javascript library for Paymongo.

A lightweight, fully-featured, modular, typescript-compatible javascript library for Paymongo.

paymongo.js A lightweight, fully-featured, modular, typescript-compatible javascript library for PayMongo. Installation npm install paymongo.js # or y

Nov 23, 2022

The one DAO to rule them all. A modular DAO written in Clarity for the Stacks blockchain.

ExecutorDAO The one DAO to rule them all. ExecutorDAO is designed to be completely modular and flexible, leveraging Clarity to the fullest extent. The

Oct 5, 2022

MagicMirror² is an open source modular smart mirror platform

MagicMirror² is an open source modular smart mirror platform

MagicMirror² is an open source modular smart mirror platform. With a growing list of installable modules, the MagicMirror² allows you to convert your hallway or bathroom mirror into your personal assistant.

Dec 29, 2022

A modular front-end framework - inspired by the server-side and Web Components.

The NX framework Home page, Docs NX is a modular front-end framework - built with ES6 and Web Components. The building blocks of NX are the core, the

Dec 5, 2022

This is my to-do list website built with html, css and JavaScript. In this project I used Webpack to bundle JavaScript and ES6 modules to write modular JavaScript.

This is my to-do list website built with html, css and JavaScript. In this project I used Webpack to bundle JavaScript and ES6 modules to write modular JavaScript.

To-Do-List App This is my to-do list website built with html, css and JavaScript. In this project I used Webpack to bundle JavaScript and ES6 modules

Sep 20, 2022

MintyJS - A Modular Backend Ecosysyem for Node

MintyJS A Modular Backend Ecosysyem for Node Explore the docs » View Demo · Report Bug · Request Feature Modules spearmint (planned) - A fully fledged

Mar 7, 2022

A simple Todo app to add list of books a user has read using HTML, CSS, Webpack, JavaScript and modular architecture

A simple Todo app to add list of books a user has read using HTML, CSS, Webpack, JavaScript and modular architecture

Minimalist A simple Todo app to add list of books a user has read. It is implemented using HTML, CSS, Webpack, JavaScript and modular architecture. A

May 9, 2022

Zero Two Bot,A fully Modular Whatsapp Bot to do everything possible in WhatsApp by Team Zero Two

Zero Two Bot,A fully Modular Whatsapp Bot to do everything possible in WhatsApp by Team Zero Two

🍭 𝗭𝗲𝗿𝗼 𝗧𝘄𝗼 𝗠𝗗 🍭 A Moduler WhatsApp Bot designed for both PM and Groups - To take your boring WhatsApp usage into a whole different level. T

Dec 25, 2022
Comments
  • Invalid code snippet in README

    Invalid code snippet in README

    In the code snippet under "Implant Bedrock middleware into your routes" in the README.md there are two else statements chained without any condition, meaning the second else statement will never be reached. I'm assuming the second else statement is meant for the outer if statement and not for the inner if statement.

    The first block also isn't closed properly so it's not syntactically correct.

    opened by firecakes 0
  • my code not work

    my code not work

    i want to try authentication with github . but apparently not working this is my code

    import { init } from "https://deno.land/x/bedrock/mod.ts"
    import { Application,Router, Context } from "https://deno.land/x/oak/mod.ts";
    import { Session } from "https://deno.land/x/[email protected]/mod.ts";
    const app = new Application()
    const router = new Router();
    app.use(router.routes());
    app.use(router.allowedMethods());
    
    const Bedrock = init({
      provider: 'Github', //example
      client_id: "64318a6ba925a18810c6",
      client_secret: "c56693666d8cdf03e440726d168c558cc992bd81",
      redirect_uri: "http://localhost:3000/privatepage",
      scope: 'read:user', //example
    });
    router.get('/oauth', Bedrock.sendRedirect);
    router.get('/privatepage', Bedrock.getToken, (ctx: Context) => {
      console.log('Successfully logged in via OAuth');
      ctx.response.body = 'Now logged in via OAuth, also have access token';
      ctx.response.redirect('/secret');
      return;
    });
    router.get('/secret', Bedrock.verifyAuth, (ctx: Context) => {
      console.log('Secret obtained!');
      ctx.response.body = 'Secret obtained!';
      ctx.response.status = 200;
      return;
    });
    router.get('/signout', Bedrock.signOut, (ctx: Context) => {
      console.log('Successfully signed out');
       ctx.response.body = 'logout!';
    
      return;
    });
    console.log("jalan port 3000")
    await app.listen({ port: 3000 });
    

    AND MY SETTING IN GITHUB homepage url : http://localhost:3000/ authorization callback url : http://localhost:3000/privatepage

    is something wrong, thank you

    opened by bobwatcherx 0
  • Digging Bedrock and some feedback

    Digging Bedrock and some feedback

    Hey guys, I reviewed all the main auth libs for Deno I could find, and I choose Bedrock. (for a few reasons: recent activity, dual auth (local/oauth), and the use of oak_sessions seems nice also) So, it seems like the best of the bunch for me anyway. 😄

    I am a very inexperienced JS dev, but I got things working it seems. I had some feedback I wanted to share:

    1. A fully working OAuth example (my use case for now) and Local example would help massively for people at my stage of learning.
    2. To me, the example handlers for /secret seem incomplete (for OAuth). I needed to gate on ctx.state.authSuccess to have the output/console.log output make any sense, and honestly, nothing made any sense to me until I figured this out by dumping the state and reviewing the source.

    Here is what I ended up with for the /secret handler:

    OAuthRouter.get("/secret", Bedrock.verifyAuth, (ctx: Context) => {
      console.log("Secret page");
      if (ctx.state.authSuccess) {
        ctx.response.body = "Secret obtained!";
      } else {
        ctx.response.body = "Not authenticated, secret not revealed!";
      }
      ctx.response.status = 200;
      return;
    });
    

    Here is my full OAuth example. I know all this Oak/routing/etc stuff is simple to you guys, but, again for newer JS developers, a fully worked example can be a lifesaver. Actually, this could be improved by putting links on the homepage, etc, etc. But it's late and I'm a bit tired. Please let me know your thoughts and/or feedback, and I appreciate you guys having created this lib!! Cam

    import {
      Application,
      Context,
      Router,
    } from "https://deno.land/x/[email protected]/mod.ts";
    import { Session } from "https://deno.land/x/[email protected]/mod.ts";
    import { init } from "https://deno.land/x/[email protected]/mod.ts";
    
    type AppState = {
      session: Session;
    };
    const app = new Application<AppState>();
    
    app.addEventListener("error", (evt) => {
      console.log(evt.error);
    });
    
    const session = new Session();
    
    // Apply sessions to your Oak application. You can also apply the middleware to specific routes instead of the whole app.
    app.use(session.initMiddleware());
    
    const OAuthRouter = new Router<AppState>();
    const Bedrock = init({
      provider: "Google", //example
      client_id: Deno.env.get("GOOG_CLIENT_ID")!,
      client_secret: Deno.env.get("GOOG_CLIENT_SECRET")!,
      redirect_uri: Deno.env.get("GOOG_AUTH_CALLBACK_URL")!,
      scope: "https://www.googleapis.com/auth/userinfo.email", //example
      prompt: "consent",
    });
    
    OAuthRouter.get("/", (context) => {
      context.response.body = "Hello world!";
    });
    
    OAuthRouter.get("/OAuth", Bedrock.sendRedirect);
    
    OAuthRouter.get("/OAuth/google", Bedrock.getToken, (ctx: Context) => {
      console.log("Successfully logged in via OAuth");
      ctx.response.body = "Now logged in via OAuth, also have access token";
      ctx.response.redirect("/secret");
      return;
    });
    
    OAuthRouter.get("/secret", Bedrock.verifyAuth, (ctx: Context) => {
      console.log("Secret page");
      if (ctx.state.authSuccess) {
        ctx.response.body = "Secret obtained!";
      } else {
        ctx.response.body = "Not authenticated, secret not revealed!";
      }
      ctx.response.status = 200;
      return;
    });
    
    OAuthRouter.get("/signout", Bedrock.signOut, (ctx: Context) => {
      console.log("Successfully signed out");
      ctx.response.redirect("/");
      return;
    });
    
    app.use(OAuthRouter.routes());
    app.use(OAuthRouter.allowedMethods());
    
    app.listen({ port: 8002 });
    
    
    opened by cameronelliott 1
Releases(v1.0.3)
Owner
OSLabs Beta
OSLabs Beta
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Opinionated collection of TypeScript definitions and utilities for Deno and Deno Deploy. With complete types for Deno/NPM/TS config files, constructed from official JSON schemas.

Schemas Note: You can also import any type from the default module, ./mod.ts deno.json import { type DenoJson } from "https://deno.land/x/[email protected]

deno911 2 Oct 12, 2022
We are creating a Library that would ensure developers do not reinvent the wheel anymore as far as Authentication is concerned. Developers can easily register and download authentication codes that suits their need at any point.

#AuthWiki Resource Product Documentation Figma Database Schema First Presentation Live Link API Documentation Individual Contributions User Activity U

Zuri Training 17 Dec 2, 2022
A small, but powerful HTTP library for Deno & Deno Deploy, built for convenience and simplicity

Wren Wren is a small, but powerful HTTP library for Deno & Deno Deploy, built for convenience and simplicity. convenient aliases for HTTP responses au

Jakub Neander 69 Dec 12, 2022
This is a simple boilerplate for a Deno website, deployed with Deno Deploy.

Simple Deno Website Boilerplate This is a simple website boilerplate built using Deno and deployed using Deno Deploy. Demo at simple-deno-website-boil

Bruno Bernardino 15 Dec 3, 2022
TypeSafe MongoDB Atlas Data API SDK for Deno & Deno Deploy

Atlas SDK atlas_sdk is a TypeSafe MongoDB Atlas Data API SDK for Deno & Deno Deploy Links Docs Import Replace LATEST_VERSION with current latest versi

Erfan Safari 20 Dec 26, 2022
Deno bindings for yoga, using Deno FFI.

deno_yoga Deno bindings for yoga, using Deno FFI. Usage flags: --allow-ffi: Requires ffi access to "yogacore.dll", "libyogacore.so", "libyogacore.dyli

迷渡 6 Feb 11, 2022
🛣️ A tiny and fast http request router designed for use with deno and deno deploy

Rutt Rutt is a tiny http router designed for use with deno and deno deploy. It is written in about 200 lines of code and is pretty fast, using an exte

Denosaurs 26 Dec 10, 2022
deno-ja (Deno Japanese community) showcase

Showcase Deno本家よりも気軽に作ったものを公開できるようなShowcaseです。 スクリーンショットの撮影方法 短めのidを決めていただいて、下記のようにスクリプトを実行してください。 deno task screenshot [url] [id] ※エラーが出る場合は、下記を実行してみ

deno-ja 17 Oct 28, 2022