Skip to main content

Auth System Behavior

1. System Behavior

1.1 Tujuan Context

Context packages/lib/src/auth menyediakan autentikasi request berbasis Bearer token untuk route API yang memakai guard NestJS.

Implementasi utama:

  • packages/lib/src/auth/datacore-jwt/datacore-jwt.guard.ts
  • packages/lib/src/auth/datacore-token/datacore-token.service.ts

1.2 Scope

Termasuk dalam scope context ini:

  • Validasi format header Authorization: Bearer <token>.
  • Verifikasi token via JWT (HS256) menggunakan process.env.SECRET.
  • Fallback ke token statis di tabel directus_users jika verifikasi JWT gagal.
  • Menyisipkan hasil user terverifikasi ke request.user.

Di luar scope context ini:

  • Otorisasi per role/permission endpoint.
  • Refresh token/session management.
  • Pembuatan token login.

2. Komponen Utama (kelas/fungsi + peran)

  1. AuthModule Peran: module global yang menyediakan dan mengekspor DatacoreTokenService. Path: packages/lib/src/auth/auth.module.ts

  2. DatacoreJwtGuard.canActivate(context) Peran: guard HTTP untuk parsing bearer token, verifikasi token, dan inject request.user. Path: packages/lib/src/auth/datacore-jwt/datacore-jwt.guard.ts

  3. DatacoreTokenService.verifyToken(token) Peran: verifikasi token dengan strategi 2 langkah (JWT -> fallback DB token statis). Path: packages/lib/src/auth/datacore-token/datacore-token.service.ts

  4. DecodedToken Peran: kontrak shape user hasil verifikasi token. Path: packages/lib/src/auth/interfaces/decoded-token.interface.ts

3. Alur System Behavior (happy path, step-by-step)

  1. Request masuk ke endpoint API yang memakai @UseGuards(DatacoreJwtGuard).
  2. Guard mengambil request.headers.authorization.
  3. Jika header tidak diawali Bearer , guard langsung throw UnauthorizedException('Invalid Authorization header').
  4. Guard mengambil token (authHeader.split(' ')[1]) lalu memanggil DatacoreTokenService.verifyToken(token).
  5. Service mencoba verifikasi JWT (HS256) dengan secret dari process.env.SECRET.
  6. Jika JWT valid, service return payload decoded sebagai DecodedToken.
  7. Jika JWT gagal diverifikasi, service query tabel directus_users berdasarkan kolom token.
  8. Jika token statis ditemukan, service membentuk object user (id, role, app_access=true, admin_access=true) lalu return.
  9. Jika token statis tidak ditemukan, service throw UnauthorizedException('Invalid token').
  10. Guard menyimpan user ke (request as any).user dan return true.

4. Flowchart (Mermaid)

5. Trigger & Input (API/event/scheduler + payload penting)

Trigger:

  • HTTP request ke controller API yang memakai DatacoreJwtGuard. Contoh path pemakaian guard:
  • apps/api/src/api/core/workflow/workflow.controller.ts
  • apps/api/src/api/core/cache/cache.controller.ts
  • apps/api/src/api/dms/kanban/kanban.controller.ts

5.1 Detail Input (tabel)

InputTypeWajibKeterangan
headers.authorizationstringYaFormat wajib Bearer <token>.
tokenstringYaDiambil dari header authorization.
process.env.SECRETstring | undefinedKondisionalDipakai saat verifikasi JWT; jika JWT gagal maka fallback ke DB token statis.

6. Output & Side Effects (DB update, publish event, external call)

Output utama:

  • Guard return true bila token valid.
  • Guard melempar UnauthorizedException bila token/header tidak valid.

Side effect:

  • Menulis request.user untuk dipakai layer controller/service berikutnya.
  • Read query ke tabel directus_users saat fallback token statis.
  • Tidak ada insert/update/delete DB.

6.1 Detail Output (tabel)

OutputTypeKeterangan
canActivate successbooleanSelalu true jika lolos autentikasi.
request.userDecodedTokenBerisi user hasil JWT atau fallback DB token statis.
Error headerUnauthorizedExceptionPesan: Invalid Authorization header.
Error tokenUnauthorizedExceptionPesan: Invalid token.

7. Error Handling

  1. Header kosong/salah format -> UnauthorizedException('Invalid Authorization header').
  2. JWT gagal diverifikasi dan token statis tidak ditemukan -> UnauthorizedException('Invalid token').
  3. Error apapun dari verifyToken(...) ditangkap guard dan dinormalisasi jadi UnauthorizedException('Invalid token').

8. Edge Cases

  1. Header Bearer tanpa token akan diproses sebagai token kosong dan berujung Invalid token.
  2. Jika JWT invalid karena secret salah/expired, sistem tetap mencoba fallback DB token statis.
  3. Fallback DB token statis selalu mengembalikan app_access=true dan admin_access=true.
  4. Guard menulis request.user memakai cast (request as any), belum ada typed request khusus.

9. Dependency & Integrasi

Dependency internal:

  1. @nestjs/common (CanActivate, UnauthorizedException, Module, Global).
  2. @nestjs/typeorm (@InjectDataSource('datacore_db')).
  3. jsonwebtoken untuk verifikasi JWT.
  4. typeorm DataSource untuk query fallback token statis.

Integrasi:

  1. apps/api/src/app.module.ts mengimpor AuthModule.
  2. Controller API yang memakai @UseGuards(DatacoreJwtGuard).

10. Data Model yang relevan (ringkas, referensi ke ERD/entitas)

  1. Tabel directus_users (dipakai pada fallback token statis):
  • kolom yang diakses: id, role, token. Path query: packages/lib/src/auth/datacore-token/datacore-token.service.ts
  1. Kontrak data user hasil verifikasi:
  • DecodedToken di packages/lib/src/auth/interfaces/decoded-token.interface.ts

11. Referensi Kode (path file yang dipakai)

  1. packages/lib/src/auth/auth.module.ts
  2. packages/lib/src/auth/datacore-jwt/datacore-jwt.guard.ts
  3. packages/lib/src/auth/datacore-token/datacore-token.service.ts
  4. packages/lib/src/auth/interfaces/decoded-token.interface.ts
  5. packages/lib/src/auth/datacore-jwt/datacore-jwt.guard.spec.ts
  6. packages/lib/src/auth/datacore-token/datacore-token.service.spec.ts
  7. apps/api/src/app.module.ts
  8. apps/api/src/api/core/workflow/workflow.controller.ts

12. Open Questions

  1. Apakah fallback DB token statis memang harus selalu memberi admin_access=true untuk semua user bertoken statis?
  2. Apakah perlu typed request khusus (misalnya RequestWithUser) agar akses request.user tidak memakai any?