GithubHelp home page GithubHelp logo

sapper-rbac's Introduction





RBAC for Sapper

js-standard-style build-status Svelte v3

Role-based access control for Sapper. Works on both the server-, and, client-side.

Install

Install as a dev dependency:

npm install --save-dev @beyonk/sapper-rbac

Usage

Define a set of route permissions in your application

  • For Sapper to work, /client/.* is automatically unrestricted.
import { Router } from '@beyonk/sapper-rbac'

const routes = new Router()
  .unrestrict('/login.*')
  .restrict('/admin/sales.*', [ 'admin', 'sales' ])
  .restrict('/admin.*', ['admin'])
  .restrict('.*', [ 'customer' ])
  .build()

export default routes

For the server-side

import { guard } from '@beyonk/sapper-rbac'
import routes from './my-routes.js'

const app = polka()
  .use(
    sessionMiddleware,
    (req, res, next) => {
      const options = {
        routes,
        deny: () => {
          res.writeHead(302, { Location: '/login' })
          return res.end()
        },
        grant: () => {
          return sapper.middleware({
            session: () => (res.user ? { user: res.user } : {})
          })(req, res, next)
        }
      }

      return guard(req.path, res.user, options)
    }
  )

sessionMiddleware

This middleware adds a user object at res.user (or null if the request isn't authenticated). The only required attribute of this user is scope which contains a list of authentication scopes that the user has:

function sessionMiddleware (req, res, next) {
  res.user = {
    scope: ['admin', 'other']
  }

  next()
}

deny

For cases where the user is denied access, call this function.

The deny function receives two parameters:

deny (path, scope) {
  // path: /some/path - the path the user attempted to access
  // scope: {
  //  given: [ 'sales.view', 'booking.create' ] - the scopes the user has
  //  required: [ 'admin.view' ] - the scopes the user required
  // }
}

grant

For cases where the user is granted access, call this function.

For the client-side

On the client side, we integrate with the page store in the root _layout.svelte:

import routes from './my-routes.js'
import { guard } from '@beyonk/sapper-rbac'
import { tick } from 'svelte'
import { stores, goto } from '@sapper/app'

const { page, session } = stores()

const options = {
  routes,
  deny: () => goto('/login')
  // we don't specify grant here, since we don't need to do anything.
}

// Listen to the page store.
page.subscribe(async v => {
  await tick() // let the previous routing finish first.
  guard(v.path, $session.user, options)
})

sapper-rbac's People

Contributors

ahpercival avatar antony avatar dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

sapper-rbac's Issues

Question about integration with sapper-authentication-demo

I've arrived here from your excellent talk and have a question about the overlap between sapper-rbac and the approaches outlined in the talk.

server.js uses these packages:

import cookieParser from 'cookie-parser' - to check the cookie
import jwt from 'jsonwebtoken' - to decode the JWT 

which completely makes sense to me in the context of your talk.

If using the sapper-rbac (as you recommend), should I follow the approach outlined in the talk AND the approach documented in the sapper-rbac readme? They seem to do two different complementary things and the sapper-rbac doesn't include anything about JWTs or cookies. If that's the case, do I need two sets of sapper middleware? One for the cookies/JWT and one for the routes?

vs code reports an error

Hello!
I can not start the dev environment, catch the error:

svana.webapp git:(auth-system) ✗ yarn run dev
yarn run v1.22.4
warning package.json: No license field
$ sapper dev
server (1.0s)
client (1.2s)
/Users/mindmind/Projects/svana/svana.webapp/node_modules/@beyonk/sapper-rbac/index.js:1
import guard from './lib/guard.js'
^^^^^^

SyntaxError: Cannot use import statement outside a module
at wrapSafe (internal/modules/cjs/loader.js:1047:16)
at Module._compile (internal/modules/cjs/loader.js:1097:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1153:10)
at Module.load (internal/modules/cjs/loader.js:977:32)
at Function.Module._load (internal/modules/cjs/loader.js:877:14)
at Module.require (internal/modules/cjs/loader.js:1019:19)
at require (internal/modules/cjs/helpers.js:77:18)
at Object. (/Users/mindmind/Projects/svana/svana.webapp/sapper/dev/server/server.js:8:18)
at Module._compile (internal/modules/cjs/loader.js:1133:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1153:10)
Server crashed
service worker (17ms)

also vs code shows error:
image

Cannot use import statement outside a module

i installed package in my sapper project when in run it give me this error

import guard from './lib/guard.js'
^^^^^^
SyntaxError: Cannot use import statement outside a module

`<Routes> was created with unknown prop 'user'` warning?

As a Svelte n00b I am very thankful for your work providing an 'auth example' and this RBAC lib 🙏🏻

I am currently trying to implement it with a back-end API providing session cookies with a JWT.
It seems I am almost there but now I notice these warnings in the console:

<Routes> was created with unknown prop 'user'

Looking into this Warning it seems it's not a big issue. But I cannot figure out where it originates from and what to do about it 😅

Where is this <Routes> component initialized and how (if at all) should I initialize it with a user prop?

Update 15-06 I cannot figure out what exactly 'fixed' this but the warning is gone after some refactoring… Leaving the issue open for now.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.