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

@programow/nest-keycloak

v2.1.0

Published

Keycloak Admin Provider for Nest.js

Downloads

13

Readme

Keycloak Admin Client for NestJs

A couple observations since this is not super well documented:

Enforce resource def function will receive as parameter the request when working with rest apis or the GqlExecutionContext when on GraphQL. When param is specified on that decorator, that we will try to find a resource with keycloak where 'param' = def(request) or 'param' = def(gqlcontext)

As per my tests, params doesn't seem reliable and could result in authorizing routes that shouldn't so we will avoid using it.

Fetch Resources will fetch absolutely all resources the user has access to on keycloak and attatch it to request.resources

Initialize KeycloakModule

Then on your app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import KeycloakModule, { AuthGuard, ResourceGuard, RoleGuard } from 'nestjs-keycloak-admin'
import { APP_GUARD } from '@nestjs/core';

@Module({
  imports: [
    KeycloakModule.register({
      baseUrl: '',
      realmName: ''
      clientSecret: '',
      clientId: ''
    })
  ],
  controllers: [AppController],
  providers: [
    {
      provide: APP_GUARD,
      useClass: AuthGuard
    },
    {provide: APP_GUARD, useClass: ResourceGuard},
    {
      provide: APP_GUARD,
      useClass: RoleGuard,
    },
  ],
})
export class AppModule {}

Resource Management using User Managed Access (UMA)

By default nestjs-keycloak-admin supports User Managed Access for managing your resources.

import { Controller, Get, Request, ExecutionContext, Post } from '@nestjs/common'
import {
  DefineResource,
  Public,
  KeycloakService,
  FetchResources,
  Resource,
  DefineScope,
  DefineResourceEnforcer,
  UMAResource,
  Scope,
} from 'nestjs-keycloak-admin'

@Controller('/organization')
@DefineResource('organization')
export class AppController {
  constructor(private readonly keycloak: KeycloakService) {}

  @Get('/hello')
  @Public()
  sayHello(): string {
    return 'life is short.'
  }

  @Get('/')
  @FetchResources()
  findAll(@Request() req: any): Resource[] {
    return req.resources as Resource[]
  }

  @Get('/:slug')
  @DefineScope('read')
  @EnforceResource({
    def: ({ params }) => params.slug,
    param: 'slug',
  })
  findBySlug(@Request() req: any): Resource {
    return req.resource as Resource
  }

  @Post('/')
  @DefineScope('create')
  async create(@Request() req: any): Promise<Resource> {
    let resource = new Resource({
      name: 'resource',
      displayName: 'My Resource',
    } as UMAResource)
      .setOwner(req.user._id)
      .setScopes([new Scope('organization:read'), new Scope('organization:write')])
      .setType('urn:resource-server:type:organization')
      .setUris(['/organization/123'])
      .setAttributes({
        valid: true,
        types: ['customer', 'any'],
      })

    resource = await this.keycloak.resourceManager.create(resource)

    // create organization on your resource server and add link to resource.id, to access it later.

    return resource
  }
}

Decorators

Here is the decorators you can use in your controllers.

| Decorator | Description | | ---------------- | --------------------------------------------------------------------------------------------------------- | | @User | Retrieves the current Keycloak logged-in user. (must be per method, unless controller is request scoped.) | | @AccessToken | Retrieves the current access token. (must be per method, unless controller is request scoped.) | | @DefineResource | Define the keycloak application resource name. | | @DefineScope | Define the keycloak resource scope (ex: 'create', 'read', 'update', 'delete') | | @EnforceResource | | | @FetchResources | | | @Public | Allow any user to use the route. | | @Roles | Keycloak realm/application roles. Prefix any realm-level roles with "realm:" (i.e realm:admin) |


  @Get('/hello')
  @Roles({roles: ['realm:admin'], mode: RoleMatchingMode.ANY})
  sayHello(@User() user: KeycloakUser, @AccessToken() accessToken): string {
    return `life is short. -${user.email}/${accessToken}`
  }

Role guard must be used with auth guard Role guard also works for clients and client roles Resource/scope guards also work with clients and their credentials. e.g. if there's some policy that only requesters with client role x are allowed.

For resource guard, scope must be specified otherwise it will be infered through the request method

To develop: Set path to the root of this repository on the dependencies of other module