{"_id":"@codejamninja/nest-keycloak-connect","_rev":"2-b59fc13de8fc5906e3e1d4d9b11ee346","name":"@codejamninja/nest-keycloak-connect","dist-tags":{"latest":"1.1.2"},"versions":{"1.1.1":{"name":"@codejamninja/nest-keycloak-connect","version":"1.1.1","description":"keycloak-nodejs-connect module for Nest","author":{"name":"Jam Risser","email":"jam@codejam.ninja"},"contributors":[{"name":"Cenk Cetinkaya","email":"mail@cenkcetinkaya.com"},{"name":"Jam Risser","email":"jam@codejam.ninja"},{"name":"John Joshua Ferrer","email":"johnjoshuaferrer@disroot.org"}],"license":"MIT","scripts":{"start:dev":"tsc -w","prebuild":"rimraf dist","build":"tsc || true","postbuild":"cpr README.md dist/ && cpr LICENSE dist/ && cpr package.json dist/","npm:publish":"npm run build && cd dist && npm publish","format":"prettier --write \"src/**/*.ts\"","lint":"tslint -p tsconfig.json -c tslint.json"},"keywords":["nestjs","keycloak","typescript"],"repository":{"type":"git","url":"git+https://github.com/codejamninja/nest-keycloak-connect.git"},"bugs":{"url":"https://github.com/codejamninja/nest-keycloak-connect/issues"},"dependencies":{"@nestjs/common":"^7.0.3","@nestjs/core":"^7.0.3","keycloak-connect":"^9.0.2","reflect-metadata":"^0.1.12","request-promise":"^4.2.5"},"devDependencies":{"@types/express":"^4.17.6","@types/request-promise":"^4.1.46","cpr":"^3.0.1","express":"^4.17.1","prettier":"^1.19.1","reflect-metadata":"^0.1.12","rimraf":"^3.0.2","rxjs":"^6.5.5","typescript":"^3.8.3"},"gitHead":"a0d84229fa800d120fc486f79fb594ebdf10ab82","homepage":"https://github.com/codejamninja/nest-keycloak-connect#readme","_id":"@codejamninja/nest-keycloak-connect@1.1.1","_nodeVersion":"12.17.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-rDE85AeV8x3Qc2/KZ7W1mTxuwassH7Pi5f5Wb+nzLcJ2h6Mz2X9tkmdrZiz0UFCfG3Bq00a53o8R7Y6zXM1HDg==","shasum":"408250a9f410c75f159d370ef72b52669b2a0989","tarball":"https://registry.npmjs.org/@codejamninja/nest-keycloak-connect/-/nest-keycloak-connect-1.1.1.tgz","fileCount":56,"unpackedSize":98595,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe0tYQCRA9TVsSAnZWagAAcIoP/RfovEI7zZRdYCuHlLCq\nItvfqw56/po1YiImsh3MBkaufr8tjalGTIt3A8ecQWZNuWzxAyIBGYxL6BQq\n/XTGNacnZVN5Wlf6QPANiC30/Y+zunCJdHNcEGxAfAVb8TWw7LR5CzFe5eGG\nR4nKuT24pneGSNI/fI3D5Woz06F+0ZshFxcn2bbuoOTQVqr7/lO5aDtbEYjZ\nhir02C7lVKdmHv4NmfxnYmklWN4qPu5gwyTPoF2LF3MbJ5j2g6XVik7nUUes\n2p5tUmJC+W2vqHRNjrLOUqDnbiJRn1An2aYLjq7UsW3PCg19PCjsaHLNIS2C\nzYeLwEDcDBT2OQgG1+GrFolPVpwrIY7ZWYVCfsCIagzJhrNFVuNHDlZpf9sv\nkccJ+EmX7kBGZh/xypINZfAuzVI+/pmbKtaGL59J+HrABQpF3dg/EA7MTGVI\ntvW/FkXk5m6uSNV/wh7FUrfqT/1uEK6EdRj3xXTJ9tbayk2O82Gip5/xsltb\nJQ1jwYAmaLDE/mfRABF5xo50lXhi1hgcoOIG22hQ+XG66U7tY7P6zQULCfTM\nma69ggD4vXd0QxhSnY1ZgOSHT0hq+X6S8bvkzDtBrrsphXVHQ52A4dIhlkFp\ns2QoGmVOGghKshOaVP7eAA3EBySiFudFY5Hl73recJh2dxiUDIORtoIp6Q1G\nNd2q\r\n=xcJU\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA05iOm2/gKyli4cLIMMcFxTm11yzIwUeCldHAMbuumBAiEA89nwFXUyEtG4ruybmNx1ZMpSxidfGfE1FOIiT2CNU4g="}]},"maintainers":[{"name":"codejamninja","email":"jam@codejam.ninja"}],"_npmUser":{"name":"codejamninja","email":"jam@codejam.ninja"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nest-keycloak-connect_1.1.1_1590875664074_0.9435395041968064"},"_hasShrinkwrap":false},"1.1.2":{"name":"@codejamninja/nest-keycloak-connect","version":"1.1.2","description":"keycloak-nodejs-connect module for Nest","author":{"name":"Jam Risser","email":"jam@codejam.ninja"},"contributors":[{"name":"Cenk Cetinkaya","email":"mail@cenkcetinkaya.com"},{"name":"Jam Risser","email":"jam@codejam.ninja"},{"name":"John Joshua Ferrer","email":"johnjoshuaferrer@disroot.org"}],"license":"MIT","scripts":{"start:dev":"tsc -w","prebuild":"rimraf dist","build":"tsc || true","postbuild":"cpr README.md dist/ && cpr LICENSE dist/ && cpr package.json dist/","npm:publish":"npm run build && cd dist && npm publish","format":"prettier --write \"src/**/*.ts\"","lint":"tslint -p tsconfig.json -c tslint.json"},"keywords":["nestjs","keycloak","typescript"],"repository":{"type":"git","url":"git+https://github.com/codejamninja/nest-keycloak-connect.git"},"bugs":{"url":"https://github.com/codejamninja/nest-keycloak-connect/issues"},"dependencies":{"@nestjs/common":"^7.0.3","@nestjs/core":"^7.0.3","keycloak-connect":"^9.0.2","reflect-metadata":"^0.1.12","request-promise":"^4.2.5"},"devDependencies":{"@types/express":"^4.17.6","@types/request-promise":"^4.1.46","cpr":"^3.0.1","express":"^4.17.1","prettier":"^1.19.1","reflect-metadata":"^0.1.12","rimraf":"^3.0.2","rxjs":"^6.5.5","typescript":"^3.8.3"},"homepage":"https://github.com/codejamninja/nest-keycloak-connect#readme","_id":"@codejamninja/nest-keycloak-connect@1.1.2","_nodeVersion":"12.17.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-bE5ju9dfmI5Dz0IHWkWgQSscYWNr7VTKptReSs9xgahhbA6Q6mbxBUpp4m3Zjn+ohRsIYLKj7uI6lqIqiIupJA==","shasum":"3355ac28474b4bd2d008c77118879254ac5abc16","tarball":"https://registry.npmjs.org/@codejamninja/nest-keycloak-connect/-/nest-keycloak-connect-1.1.2.tgz","fileCount":33,"unpackedSize":30126,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe0tatCRA9TVsSAnZWagAA18IP/Ai7dYnWJ8UBRQz4D1Av\n4DCr1sqpjqEF0HdR0j8JS/YAeHeX3SCgwkqKFos2XRZNRyCV0liNgJ/esWrH\nzt6u8MZd5nc2hzNSiiV+qCOk3aHYpT3bkz5Zlcbmdik6uOf7zwSI/WOfLT4G\nA8flTpvgZZ6xl7phGZ1v/oK0OUYveTKIMBU2tOJdmnUvgvfBczP6naWg1anr\nWZOaJQ0TkOa2SuBXspsEj2+Zj8mVlsSlfLASjhSS1zjGMX8ZUlwu2PQNTjDQ\nJ8wGC7iJ82B7T4hhGJAcUcyxNBcQiH/x+6VbmGWvtD95nX1MbKq+cMHpQYSj\nqClRry9JrhxNqNiGxnix8/b6JCxWXXqcx9WfsRTa9mIq5M46B0f25GAHITFz\ncBMMLaHtvRl9qObXhuyJvHxfGZsWKKzl1kiiB95VBQfeXSSqXXvqiIx8gODD\ncL3BZeMRlzkHu2ftOVhyIS4Vx/vSfZkcD+i29J+avCbzweXNtdqdu127LrVH\nuX+bRwPclvU4dE/0DSoYzP49iwWGADW/zTkZMALl83Ql2U+Uab72Pvlbo848\ndsTuiZd9tvSSWC43p3/gtpiv+FGid8cYJcI7pG/F0JWoR4vSkGgR28j/zRKw\nfvVaQeJz39EE7+9A6nCBZ3odfBAtv3C5BBvBp1Hc8n8PJ1P0uLCDr2FGU+cq\n/xqc\r\n=Z6FI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIARCBE6tTJcNfHTSLp322OVO8PXl6wJY2aH/mlIT/LhQAiEAhCYTUeiIhkdeB9YBY/04mEVhZi3VUuMxzcyOAE69YLs="}]},"maintainers":[{"name":"codejamninja","email":"jam@codejam.ninja"}],"_npmUser":{"name":"codejamninja","email":"jam@codejam.ninja"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/nest-keycloak-connect_1.1.2_1590875820949_0.886504802054817"},"_hasShrinkwrap":false}},"time":{"created":"2020-05-30T21:54:24.043Z","1.1.1":"2020-05-30T21:54:24.201Z","modified":"2022-04-05T00:03:07.923Z","1.1.2":"2020-05-30T21:57:01.039Z"},"maintainers":[{"name":"codejamninja","email":"jam@codejam.ninja"}],"description":"keycloak-nodejs-connect module for Nest","homepage":"https://github.com/codejamninja/nest-keycloak-connect#readme","keywords":["nestjs","keycloak","typescript"],"repository":{"type":"git","url":"git+https://github.com/codejamninja/nest-keycloak-connect.git"},"contributors":[{"name":"Cenk Cetinkaya","email":"mail@cenkcetinkaya.com"},{"name":"Jam Risser","email":"jam@codejam.ninja"},{"name":"John Joshua Ferrer","email":"johnjoshuaferrer@disroot.org"}],"author":{"name":"Jam Risser","email":"jam@codejam.ninja"},"bugs":{"url":"https://github.com/codejamninja/nest-keycloak-connect/issues"},"license":"MIT","readme":"# Nest Keycloak Connect\r\n\r\nAn adapter for [keycloak-nodejs-connect](https://github.com/keycloak/keycloak-nodejs-connect).\r\n\r\n## Features\r\n\r\n- Protect your resources using [Keycloak's Authorization Services](https://www.keycloak.org/docs/latest/authorization_services/).\r\n- Simply add `@Resource` and `@Scopes` in your controllers and you're good to go.\r\n- Compatible with [Fastify](https://github.com/fastify/fastify) platform.\r\n\r\n## Installation\r\n\r\n### Yarn\r\n\r\n```bash\r\nyarn add nest-keycloak-connect\r\n```\r\n\r\n### NPM\r\n\r\n```bash\r\nnpm install nest-keycloak-connect --save\r\n```\r\n\r\n## Getting Started\r\n\r\nRegister the module in app.module.ts\r\n\r\n```typescript\r\nimport { Module } from '@nestjs/common';\r\nimport { KeycloakConnectModule, ResourceGuard, AuthGuard } from 'nest-keycloak-connect';\r\n\r\n@Module({\r\n  imports: [KeycloakConnectModule.register({\r\n    authServerUrl: 'http://localhost:8080/auth',\r\n    realm: 'master',\r\n    clientId: 'my-nestjs-app',\r\n    secret: 'secret',\r\n  })],\r\n  providers: [\r\n    // These are in order, see https://docs.nestjs.com/guards#binding-guards\r\n    // for more information\r\n\r\n    // This adds a global level authentication guard, you can also have it scoped\r\n    // if you like.\r\n    //\r\n    // Will return a 401 unauthorized when it is unable to\r\n    // verify the JWT token or Bearer header is missing.\r\n    {\r\n      provide: APP_GUARD,\r\n      useClass: AuthGuard,\r\n    },\r\n    // This adds a global level resource guard, which is permissive.\r\n    // Only controllers annotated with @Resource and methods with @Scopes\r\n    // are handled by this guard.\r\n    {\r\n      provide: APP_GUARD,\r\n      useClass: ResourceGuard,\r\n    },\r\n  ],\r\n})\r\nexport class AppModule {}\r\n```\r\n\r\nCreate Public Paths\r\n\r\n```typescript\r\nimport { Resource, Scopes, KeycloakService, Roles, KeycloakedRequest } from '@cenkce/nest-keycloak-connect';\r\nimport { Controller, Get, Delete, Put, Post, Param } from '@nestjs/common';\r\n\r\n@Controller()\r\n@Resource(Product.name)\r\nexport class AppController {\r\n  constructor(private service: keycloakService: KeycloakService) {}\r\n\r\n  @PublicPath()\r\n  @Get('login')\r\n  @Render('login.hbs')\r\n  login(@Res() resp: FastifyReply<any>, req: KeycloakedRequest<FastifyRequest>) {\r\n    console.log('/login');\r\n    if(req.grant){\r\n      resp.status(302).redirect('/notifications/direct');\r\n      return {}\r\n    }\r\n\r\n    return {};\r\n  }\r\n\r\n  @PublicPath()\r\n  @Post('login')\r\n  async auth(@Res() resp: FastifyReply<any>, @Body() body, @Session() session) {\r\n    try {\r\n      const res = await this.keycloakService.login(body.user, body.password);\r\n    \r\n      if(typeof res === 'string' && res.indexOf('access_token') !== -1){\r\n        session.auth = true;\r\n        session.token = res;\r\n        resp.status(302).redirect('/notifications/direct');\r\n      }\r\n    } catch(e) {\r\n      throw new HttpException({\r\n        status: HttpStatus.INTERNAL_SERVER_ERROR,\r\n        error: e.message,\r\n      }, HttpStatus.INTERNAL_SERVER_ERROR);\r\n    }\r\n  }\r\n\r\n  @PublicPath()\r\n  @Get('logout')\r\n  logout(@Res() resp: FastifyReply<any>, @Res() req:FastifyRequest){\r\n    req.session.sessionId && req.destroySession((e) => {\r\n      throw new HttpException({\r\n        status: HttpStatus.INTERNAL_SERVER_ERROR,\r\n        error: e.message,\r\n      }, HttpStatus.INTERNAL_SERVER_ERROR);\r\n    });\r\n    resp.status(302).redirect('/login');\r\n  }\r\n}\r\n```\r\n\r\nAuthorization Using **@Roles()** and **@Scopes()**\r\n\r\n- Usage of @Roles decorater\r\n  - @Roles(\"role_name\", /* or */, \"role_name2\")\r\n  - @Roles([\"role_name\", /* and */, \"role_name2\"])\r\n  - @Roles([\"role_name\", /* and */, \"role_name2\"], /* or */ \"role_name3\" )\r\n  - @Roles([\"role_name\", /* and */, \"role_name2\"], /* or */ [\"role_name3\", /* and */, \"role_name4\"] )\r\n\r\n\r\n\r\n```typescript\r\nimport { Resource, Scopes } from '@cenkce/nest-keycloak-connect';\r\nimport { Controller, Get, Delete, Put, Post, Param } from '@nestjs/common';\r\nimport { Product } from './product';\r\nimport { ProductService } from './product.service';\r\n\r\n@Controller()\r\n@Resource(Product.name)\r\nexport class ProductController {\r\n  constructor(private service: ProductService) {}\r\n\r\n  @Get()\r\n  @Roles(\"realm:admin\")\r\n  @Scopes('View', 'View All')\r\n  async findAll() {\r\n    return await this.service.findAll();\r\n  }\r\n\r\n  @Get(':code')\r\n  @Roles(\"realm:admin\", \"realm:user\")\r\n  @Scopes('View')\r\n  async findByCode(@Param('code') code: string) {\r\n    return await this.service.findByCode(code);\r\n  }\r\n\r\n  @Post()\r\n  @Scopes('Create')\r\n  async create(@Body product: Product) {\r\n    return await this.service.create(product);\r\n  }\r\n\r\n  @Delete(':code')\r\n  @Scopes('Delete')\r\n  async deleteByCode(@Param('code') code: string) {\r\n    return await this.service.deleteByCode(code);\r\n  }\r\n\r\n  @Put(':code')\r\n  @Scopes('Edit')\r\n  async update(@Param('code') code: string, @Body product: Product) {\r\n    return await this.service.update(code, product);\r\n  }\r\n}\r\n```\r\n","readmeFilename":"README.md"}