{"_id":"@agdsoftware/nestjs-sso","_rev":"3-6f0d1d77288d1bf82c55cd1720feb7d4","name":"@agdsoftware/nestjs-sso","dist-tags":{"latest":"1.1.1"},"versions":{"1.1.0":{"name":"@agdsoftware/nestjs-sso","version":"1.1.0","keywords":["sso","keycloak","oidc","authorization","iam","agd"],"license":"UNLICENSED","_id":"@agdsoftware/nestjs-sso@1.1.0","maintainers":[{"name":"agdmgv","email":"yazilimvebilisim@agd.org.tr"}],"homepage":"https://github.com/karademirmustafa/agd-sso/tree/main/packages/nestjs-sso#readme","bugs":{"url":"https://github.com/karademirmustafa/agd-sso/issues"},"dist":{"shasum":"729ad73b961d27b164b7ea0e555d281781b4686b","tarball":"https://registry.npmjs.org/@agdsoftware/nestjs-sso/-/nestjs-sso-1.1.0.tgz","fileCount":38,"integrity":"sha512-KodE0kTyYI+otuMv2te5BnqcXx9pWHUtQud3bjF4rku9r5V8K3cSMKCts+d6DoBjwxFnmTx0fajAyZhHCyu7/g==","signatures":[{"sig":"MEYCIQDrM0LNGrSi81k7DSGcF6gC6zEYp84nEeSXKWnlPO/AjgIhAJ08Br5OlBM20mWwab9TyGNFOSdlxOcBktywLx1UPmAf","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":98187},"main":"dist/index.js","type":"commonjs","_from":"file:/Users/karademir/yazilimvebilisimkomisyonu/52.Dönem/projeler/sso-yetkilendirme/dist-sdk/agdsoftware-nestjs-sso-1.1.0.tgz","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./testing":{"types":"./dist/testing.d.ts","default":"./dist/testing.js"},"./typeorm":{"types":"./dist/typeorm.d.ts","default":"./dist/typeorm.js"},"./package.json":"./package.json"},"scripts":{"test":"jest --passWithNoTests","build":"tsc -p tsconfig.json","clean":"rm -rf dist","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"agdmgv","email":"yazilimvebilisim@agd.org.tr"},"_resolved":"/Users/karademir/yazilimvebilisimkomisyonu/52.Dönem/projeler/sso-yetkilendirme/dist-sdk/agdsoftware-nestjs-sso-1.1.0.tgz","_integrity":"sha512-KodE0kTyYI+otuMv2te5BnqcXx9pWHUtQud3bjF4rku9r5V8K3cSMKCts+d6DoBjwxFnmTx0fajAyZhHCyu7/g==","repository":{"url":"git+https://github.com/karademirmustafa/agd-sso.git","type":"git","directory":"packages/nestjs-sso"},"_npmVersion":"11.8.0","description":"AGD SSO/IAM için NestJS entegrasyon paketi — guard zinciri, dekoratörler, birim kapsamı","directories":{},"sideEffects":false,"_nodeVersion":"24.13.1","dependencies":{"@agdsoftware/sso-client":"1.1.0"},"publishConfig":{"access":"public"},"typesVersions":{"*":{"testing":["dist/testing.d.ts"],"typeorm":["dist/typeorm.d.ts"]}},"//dependencies":"pnpm pack/publish sırasında 'workspace:*' gerçek sürüme (1.0.0) çevrilir; tarball dışarıda da kurulabilir.","_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.8.1","typeorm":"^0.3.28","typescript":"^5.5.4","@types/node":"^20.14.0","@nestjs/core":"^11.0.1","@nestjs/common":"^11.0.1","@types/express":"^5.0.0","reflect-metadata":"^0.2.2"},"peerDependencies":{"rxjs":"^7.0.0","express":"^4.0.0 || ^5.0.0","typeorm":"^0.3.0","@nestjs/core":"^10.0.0 || ^11.0.0","@nestjs/common":"^10.0.0 || ^11.0.0","reflect-metadata":"^0.1.13 || ^0.2.0"},"peerDependenciesMeta":{"typeorm":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/nestjs-sso_1.1.0_1786336994913_0.832474139242958","host":"s3://npm-registry-packages-npm-production"},"deprecated":"→ @agdsoftware/sso-sdk/nestjs"},"1.1.1":{"name":"@agdsoftware/nestjs-sso","version":"1.1.1","keywords":["nestjs","sso","keycloak","oidc","authorization","permissions","rbac","guard","decorator","iam"],"license":"UNLICENSED","_id":"@agdsoftware/nestjs-sso@1.1.1","maintainers":[{"name":"agdmgv","email":"yazilimvebilisim@agd.org.tr"}],"homepage":"https://github.com/karademirmustafa/agd-sso/tree/main/packages/nestjs-sso#readme","bugs":{"url":"https://github.com/karademirmustafa/agd-sso/issues"},"dist":{"shasum":"84a73f799587a59fad3afa4196c14d1dc9c03902","tarball":"https://registry.npmjs.org/@agdsoftware/nestjs-sso/-/nestjs-sso-1.1.1.tgz","fileCount":38,"integrity":"sha512-Xfl68U+TusgvaxB5CmUaEgeatWXjrvUKJPukRuKs5BQN/bCGLtuU75FSy2d88iUKQnF1YChSQWAjtmIxxY+ZqQ==","signatures":[{"sig":"MEUCIFwsBdbJjqjdVTFLhL4zEarSrF0ap2xvTDY0XInqfATpAiEAoM+5ot/m2jYAeyDAb6gL+DW5lh6h+BZZ6+w2/qmcI2E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":98422},"main":"dist/index.js","type":"commonjs","_from":"file:/Users/karademir/yazilimvebilisimkomisyonu/52.Dönem/projeler/sso-yetkilendirme/dist-sdk/agdsoftware-nestjs-sso-1.1.1.tgz","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./testing":{"types":"./dist/testing.d.ts","default":"./dist/testing.js"},"./typeorm":{"types":"./dist/typeorm.d.ts","default":"./dist/typeorm.js"},"./package.json":"./package.json"},"scripts":{"test":"jest --passWithNoTests","build":"tsc -p tsconfig.json","clean":"rm -rf dist","typecheck":"tsc -p tsconfig.json --noEmit"},"_npmUser":{"name":"agdmgv","email":"yazilimvebilisim@agd.org.tr"},"_resolved":"/Users/karademir/yazilimvebilisimkomisyonu/52.Dönem/projeler/sso-yetkilendirme/dist-sdk/agdsoftware-nestjs-sso-1.1.1.tgz","_integrity":"sha512-Xfl68U+TusgvaxB5CmUaEgeatWXjrvUKJPukRuKs5BQN/bCGLtuU75FSy2d88iUKQnF1YChSQWAjtmIxxY+ZqQ==","repository":{"url":"git+https://github.com/karademirmustafa/agd-sso.git","type":"git","directory":"packages/nestjs-sso"},"_npmVersion":"11.8.0","description":"Keycloak/OIDC tabanlı merkezi yetkilendirme için NestJS entegrasyonu — guard zinciri, izin dekoratörleri, birim bazlı satır kapsamı, hazır /sso/me ucu ve sağlık göstergesi.","directories":{},"sideEffects":false,"_nodeVersion":"24.13.1","dependencies":{"@agdsoftware/sso-client":"1.1.1"},"publishConfig":{"access":"public"},"typesVersions":{"*":{"testing":["dist/testing.d.ts"],"typeorm":["dist/typeorm.d.ts"]}},"//dependencies":"pnpm pack/publish sırasında 'workspace:*' gerçek sürüme (1.0.0) çevrilir; tarball dışarıda da kurulabilir.","_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.8.1","typeorm":"^0.3.28","typescript":"^5.5.4","@types/node":"^20.14.0","@nestjs/core":"^11.0.1","@nestjs/common":"^11.0.1","@types/express":"^5.0.0","reflect-metadata":"^0.2.2"},"peerDependencies":{"rxjs":"^7.0.0","express":"^4.0.0 || ^5.0.0","typeorm":"^0.3.0","@nestjs/core":"^10.0.0 || ^11.0.0","@nestjs/common":"^10.0.0 || ^11.0.0","reflect-metadata":"^0.1.13 || ^0.2.0"},"peerDependenciesMeta":{"typeorm":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/nestjs-sso_1.1.1_1786337635634_0.4529938327075429","host":"s3://npm-registry-packages-npm-production"},"deprecated":"→ @agdsoftware/sso-sdk/nestjs"}},"time":{"created":"2026-08-10T04:43:14.728Z","modified":"2026-08-10T11:55:04.644Z","1.1.0":"2026-08-10T04:43:15.050Z","1.1.1":"2026-08-10T04:53:55.777Z"},"bugs":{"url":"https://github.com/karademirmustafa/agd-sso/issues"},"license":"UNLICENSED","homepage":"https://github.com/karademirmustafa/agd-sso/tree/main/packages/nestjs-sso#readme","keywords":["nestjs","sso","keycloak","oidc","authorization","permissions","rbac","guard","decorator","iam"],"repository":{"url":"git+https://github.com/karademirmustafa/agd-sso.git","type":"git","directory":"packages/nestjs-sso"},"description":"Keycloak/OIDC tabanlı merkezi yetkilendirme için NestJS entegrasyonu — guard zinciri, izin dekoratörleri, birim bazlı satır kapsamı, hazır /sso/me ucu ve sağlık göstergesi.","maintainers":[{"name":"agdmgv","email":"yazilimvebilisim@agd.org.tr"}],"readme":"# @agdsoftware/nestjs-sso\n\nKimliği **Keycloak/OIDC**'den, yetkiyi **merkezi bir IAM servisinden** alan\n**NestJS** uygulamaları için entegrasyon paketi.\n\n> **Tek cümle:** token *\"bu kişi kim\"* der, IAM *\"ne yapabilir\"* der.\n> Bu paket ikisini bağlar; alan bilginize karışmaz.\n\n`@agdsoftware/sso-client` ham istemcidir (Express, Fastify, script…). Bu paket onun\nNestJS karşılığıdır: guard zinciri, dekoratörler, birim kapsamı ve `/sso/me`.\n\n## Kurulum\n\n```bash\nnpm i @agdsoftware/nestjs-sso\n```\n\nRegistry'siz ortamda tarball ile: `pnpm sdk:pack` → `npm i\n./vendor/agdsoftware-sso-client-*.tgz ./vendor/agdsoftware-nestjs-sso-*.tgz` (ikisi tek komutta,\nyoksa npm eksik bağımlılığı registry'de arar).\n\n## 3 adımda bağlanma\n\n**1. Modül**\n\n```ts\n// app.module.ts\nimport { SsoModule } from '@agdsoftware/nestjs-sso';\n\n@Module({\n  imports: [\n    // Standart ortam değişkenlerini okur ve DOĞRULAR:\n    //   SSO_ISSUER · SSO_AUDIENCE · IAM_BASE_URL\n    // Eksik varsa süreç AÇILIŞTA durur — eksik yapılandırmayla ayağa kalkıp\n    // ilk isteğe kadar sağlıklı görünmek, sorunu üretimde bulmaktır.\n    SsoModule.forRootFromEnv({\n      publicMetadataKeys: ['isPublic'],  // var olan @Public() dekoratörünüz\n    }),\n  ],\n})\nexport class AppModule {}\n```\n\nDeğerleri elle vermek isterseniz `forRoot({ issuer, audience, iamBaseUrl, … })`\nve `forRootAsync({ useFactory })` da durur.\n\nGuard'lar `APP_GUARD` olarak **sırayla** kaydedilir: kimlik → bağlam → karar.\n\n**2. Controller**\n\n```ts\n@Controller('toplantilar')\nexport class MeetingsController {\n  @Get()\n  @RequirePermission('mgkys:toplanti:goruntule')\n  list(@CurrentContext() ctx: SsoContext) { ... }\n\n  @Get('profilim')\n  @SelfScoped()                       // izin yok, kimlik yeter\n  me(@CurrentSsoUser() user: SsoIdentity) { ... }\n}\n```\n\nDekoratör taşımayan handler **403** alır (fail-closed). Unutulan uç açık kalmaz.\n\n**3. Satır kapsamı**\n\nHer kaydınıza sahibi birimin Keycloak yolunu yazın (`GroupPath` = `/İzmir/Konak`):\n\n```ts\nimport { applyGroupScope } from '@agdsoftware/nestjs-sso/typeorm';\nimport { ownerGroupPath, assertInScope } from '@agdsoftware/nestjs-sso';\n\n// listeleme\napplyGroupScope(qb, ctx);                       // ctx = /İzmir → /İzmir ve altı\n\n// oluşturma\nmeeting.GroupPath = ownerGroupPath(ctx);        // istemciden gelen birim kabul edilmez\n\n// güncelleme/silme — okuma filtresi tek başına yetmez\nassertInScope(ctx, meeting.GroupPath);\n```\n\n## Dekoratörler\n\n| Dekoratör | Anlamı |\n|---|---|\n| `@RequirePermission(code)` | Bu izin yoksa 403 |\n| `@RequireAnyPermission(a, b)` | Herhangi biri yeter (VEYA) |\n| `@PermissionResource('mgkys:toplanti')` | **Sınıf** seviyesi; devralınan `add/get/getAll/update/delete` için izni metot adından türetir |\n| `@SelfScoped()` | Kimlik yeter; handler **yalnız** `@CurrentSsoUser()` kimliğini kullanmalı |\n| `@AnyAuthenticated()` | Kimlik yeter; yanıt kişiye göre değişmez (referans veriler) |\n| `@SsoPublic()` | Token bile gerekmez |\n| `@CurrentContext()` / `@CurrentSsoUser()` / `@CurrentGroup()` | Parametre dekoratörleri |\n\n`@RequirePermission` **sınıf seviyesinde yasaktır** (TypeError): sınıfa yazılan\nizin sonradan eklenen her handler'a sessizce miras kalır.\n\n## Genişletme noktaları\n\nGlobal sağlayıcı olarak verin; verilmezse makul varsayılan çalışır.\n\n```ts\n@Global()\n@Module({\n  providers: [\n    { provide: SSO_USER_RESOLVER, useClass: UsersLinkService },  // sub → Users.Id\n    { provide: SSO_CACHE, useClass: RedisSsoCache },             // yoksa süreç içi bellek\n  ],\n  exports: [SSO_USER_RESOLVER, SSO_CACHE],\n})\nexport class SsoBridgeModule {}\n```\n\n- **`SsoUserResolver`** — SSO kullanıcısını kendi tablonuza bağlar. `null`\n  dönerse istek `403 SSO_USER_NOT_LINKED` alır (sessizce yeni kullanıcı sayılmaz).\n- **`SsoCacheAdapter`** — çok instance'lı kurulumda Redis verin.\n\n## Katalog doğrulaması\n\nİzin kodlarınızı bir katalogda toplayın ve dekoratörlere tanıtın:\n\n```ts\n// permissions/catalog.ts (dosyanın sonunda)\nregisterPermissionCatalog((code) => CODE_SET.has(code));\n```\n\nKatalogda olmayan bir kod **açılışta** TypeError verir. Yakalanmazsa o uç\nsessizce herkese kapanır ve 403'ün nedeni aylarca aranır.\n\n## Hata sözleşmesi\n\n| Durum | Kod | Anlamı |\n|---|---|---|\n| 401 | `SSO_TOKEN_MISSING` / `SSO_TOKEN_INVALID` | Kimlik yok/geçersiz |\n| 403 | `SSO_USER_NOT_LINKED` | Kimlik var, uygulamada karşılığı yok |\n| 403 | `SSO_GROUP_NOT_MEMBER` | İstenen birimin üyesi değil |\n| 403 | `IAM_PERMISSION_DENIED` | Yetki yok (hangi izin olduğu **söylenmez**) |\n| 403 | `IAM_SCOPE_DENIED` / `IAM_RESOURCE_DENIED` | Kayıt yetki alanı dışında |\n| 503 | `IAM_UNAVAILABLE` | IAM'e ulaşılamadı — **yetkisizlik değildir** |\n\n503'ü 403'e katlamayın: bir kesintiyi yetki hatası gibi göstermek ekibi günlerce\nyanlış yerde arattırır.\n\n## Testler\n\nGuard'ları mock'lamayın — mock'lanmış guard her zaman \"geçti\" der ve testler\nyetki hatalarını göremez. Bağlamı kurgulayın:\n\n```ts\nimport { createTestSsoContext } from '@agdsoftware/nestjs-sso/testing';\n\nconst ctx = createTestSsoContext({\n  permissions: ['mgkys:toplanti:goruntule'],\n  group: { path: '/İzmir/Konak', unitType: 'ILCE' },\n});\n```\n\n## Bilinen tuzaklar\n\n- **`issuer` TAM eşleşmeli.** `127.0.0.1` yazmak `localhost` token'ını düşürür.\n- **`audience` doğrulanmazsa** başka bir uygulama için üretilmiş geçerli token\n  kabul edilir: kullanıcı doğru, uygulama yanlıştır.\n- **Yerel izin cache'i 60 sn'yi geçmesin** — geri alınan yetki o kadar süre yaşar.\n- **`X-Organization-Group-Id` tek başına güvenilmez**; paket her istekte\n  kullanıcının IAM'deki birim listesiyle doğrular.\n","readmeFilename":"README.md"}