@fluojs/jwt 1.0.0-beta.2 → 1.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ko.md CHANGED
@@ -110,7 +110,7 @@ const principal = await verifier.verifyAccessToken(token);
110
110
  // principal: { subject: 'user-123', roles: ['admin'], scopes: ['read:profile'], ... }
111
111
  ```
112
112
 
113
- `JwtService.sign(payload, { expiresIn })`를 사용할 때는 payload 안에 기존 `exp` 값이 있더라도 호출 시점의 `expiresIn` 재정의가 항상 우선합니다. 따라서 토큰 수명은 호출 위치에서 결정적으로 제어됩니다.
113
+ `JwtService.sign(payload, { expiresIn })`를 사용할 때는 payload 안에 기존 `exp` 값이 있더라도 호출 시점의 `expiresIn` 재정의가 항상 우선합니다. 따라서 토큰 수명은 호출 위치에서 결정적으로 제어됩니다. `expiresIn`은 초 단위의 0 이상 숫자 또는 `60s`, `15m`, `1h`, `7d` 같은 짧은 duration 문자열을 받을 수 있습니다.
114
114
 
115
115
  ## 일반적인 패턴
116
116
 
@@ -150,6 +150,12 @@ const verifier = new DefaultJwtVerifier({
150
150
 
151
151
  `JwtService.verify(token, options)`는 호출 단위의 알고리즘/클레임 정책 재정의(`issuer`, `audience`, `clockSkewSeconds`, `maxAge`, `requireExp`)를 적용하더라도, 내부 JWKS client나 정적 key-resolution cache를 다시 만들지 않습니다. 호출 단위 검증은 `jwksUri`, `keys[]`, `publicKey`, `secret`, `secretOrKeyProvider` 같은 구성된 key source 자체를 교체하지는 않습니다.
152
152
 
153
+ 호환되는 키가 여러 개 설정되어 있으면 `kid`가 검증 키를 구분합니다. 호환되는 정적 키가 하나뿐이면 `kid` 없이도 토큰을 검증할 수 있고, JWKS 기반 검증은 원격 key set과 cache policy를 따릅니다.
154
+
155
+ ### 리프레시 토큰
156
+
157
+ `RefreshTokenService`는 전용 HMAC refresh-token 경로를 사용합니다. `refreshToken.secret`은 access-token 서명 키와 별도로 설정하세요. Rotation은 재사용된 토큰을 안정적으로 감지할 수 있도록 atomic `RefreshTokenStore.consume(...)` 구현을 필요로 합니다.
158
+
153
159
  ## 설정 가드레일
154
160
 
155
161
  JWT 서명과 검증에는 `algorithms`에 지원되는 알고리즘이 하나 이상 필요합니다. 기본 signer는 `HS256`, `HS384`, `HS512`, `RS256`, `RS384`, `RS512`, `ES256`, `ES384`, `ES512`를 지원하며, 빈 알고리즘 목록은 모호한 토큰을 발행하거나 수락하지 않도록 즉시 실패합니다.
@@ -163,10 +169,19 @@ JWT 서명과 검증에는 `algorithms`에 지원되는 알고리즘이 하나
163
169
  - `DefaultJwtSigner`: 클레임 자동 채우기 기능이 포함된 토큰 발행 클래스입니다.
164
170
  - `DefaultJwtVerifier`: 토큰 검증 및 정규화를 담당하는 클래스입니다.
165
171
  - `JwtService`: 서명과 검증 기능을 결합한 편의용 파사드(facade)입니다.
172
+ - `JwksClient`: 제한된 요청 시간 안에서 원격 JWKS 키를 가져오고 캐싱합니다.
173
+ - `RefreshTokenService`: `refreshToken` 옵션이 구성된 경우 refresh token을 발행, 회전, 폐기합니다.
166
174
 
167
175
  ### 타입
168
176
  - `JwtPrincipal`: 정규화된 사용자 식별 객체 (`subject`, `roles`, `scopes`, `claims`).
169
177
  - `JwtVerifierOptions`: 알고리즘, 키, 검증 정책 설정을 위한 타입입니다.
178
+ - `SignOptions`, `VerifyOptions`: 호출 단위 서명 및 검증 재정의 타입입니다.
179
+ - `JwtClaims`, `JwtSigner`, `JwtVerifier`, `JwtKeyEntry`, `JwtAlgorithm`: 공개 서명 및 검증 계약입니다.
180
+
181
+ ### 에러와 diagnostics
182
+ - `JwtVerificationError`, `JwtInvalidTokenError`, `JwtExpiredTokenError`, `JwtConfigurationError`: 타입이 지정된 JWT 실패입니다.
183
+ - `createJwtPlatformStatusSnapshot(...)`, `createJwtPlatformDiagnosticIssues(...)`: status 및 diagnostic helper입니다.
184
+ - `JWT_OPTIONS`, `HMAC_HASH`, `ASYMMETRIC_HASH`: 모듈과 검증 레이어에서 사용하는 export token/constant입니다.
170
185
 
171
186
  ## 관련 패키지
172
187
 
package/README.md CHANGED
@@ -110,7 +110,7 @@ const principal = await verifier.verifyAccessToken(token);
110
110
  // principal: { subject: 'user-123', roles: ['admin'], scopes: ['read:profile'], ... }
111
111
  ```
112
112
 
113
- When you use `JwtService.sign(payload, { expiresIn })`, the per-call `expiresIn` override always wins over any pre-existing `payload.exp` value so token lifetime stays deterministic at the call site.
113
+ When you use `JwtService.sign(payload, { expiresIn })`, the per-call `expiresIn` override always wins over any pre-existing `payload.exp` value so token lifetime stays deterministic at the call site. `expiresIn` accepts a non-negative number of seconds or short duration strings such as `60s`, `15m`, `1h`, or `7d`.
114
114
 
115
115
  ## Common Patterns
116
116
 
@@ -150,6 +150,12 @@ const verifier = new DefaultJwtVerifier({
150
150
 
151
151
  `JwtService.verify(token, options)` applies per-call algorithm and claim-policy overrides (`issuer`, `audience`, `clockSkewSeconds`, `maxAge`, `requireExp`) without rebuilding the underlying JWKS client or static key-resolution cache. Per-call verification does not replace configured key sources such as `jwksUri`, `keys[]`, `publicKey`, `secret`, or `secretOrKeyProvider`.
152
152
 
153
+ When multiple compatible keys are configured, `kid` disambiguates the verification key. A single compatible static key can verify tokens without `kid`; JWKS-backed verification relies on the remote key set and its cache policy.
154
+
155
+ ### Refresh tokens
156
+
157
+ `RefreshTokenService` uses a dedicated HMAC refresh-token path. Configure `refreshToken.secret` separately from access-token signing keys. Rotation requires an atomic `RefreshTokenStore.consume(...)` implementation so replayed tokens can be detected reliably.
158
+
153
159
  ## Configuration Guardrails
154
160
 
155
161
  JWT signing and verification require at least one supported algorithm in `algorithms`. The built-in signer supports `HS256`, `HS384`, `HS512`, `RS256`, `RS384`, `RS512`, `ES256`, `ES384`, and `ES512`; configuration with an empty algorithm list fails fast instead of issuing or accepting ambiguous tokens.
@@ -163,10 +169,19 @@ Access-token TTL must also be a positive finite number. When `accessTokenTtlSeco
163
169
  - `DefaultJwtSigner`: Handles token issuance with default claim filling.
164
170
  - `DefaultJwtVerifier`: Handles token validation and normalization.
165
171
  - `JwtService`: A convenience facade combining signing and verification.
172
+ - `JwksClient`: Fetches and caches remote JWKS keys with bounded request timeouts.
173
+ - `RefreshTokenService`: Issues, rotates, and revokes refresh tokens when `refreshToken` options are configured.
166
174
 
167
175
  ### Types
168
176
  - `JwtPrincipal`: The normalized identity object (`subject`, `roles`, `scopes`, `claims`).
169
177
  - `JwtVerifierOptions`: Configuration for algorithms, keys, and validation policy.
178
+ - `SignOptions` and `VerifyOptions`: Per-call signing and verification overrides.
179
+ - `JwtClaims`, `JwtSigner`, `JwtVerifier`, `JwtKeyEntry`, `JwtAlgorithm`: Public signing and verification contracts.
180
+
181
+ ### Errors and diagnostics
182
+ - `JwtVerificationError`, `JwtInvalidTokenError`, `JwtExpiredTokenError`, `JwtConfigurationError`: Typed JWT failures.
183
+ - `createJwtPlatformStatusSnapshot(...)` and `createJwtPlatformDiagnosticIssues(...)`: Status and diagnostic helpers.
184
+ - `JWT_OPTIONS`, `HMAC_HASH`, `ASYMMETRIC_HASH`: Exported tokens/constants used by the module and verification layer.
170
185
 
171
186
  ## Related Packages
172
187
 
package/dist/module.d.ts CHANGED
@@ -6,7 +6,9 @@ type ModuleType = Constructor;
6
6
  */
7
7
  export declare class JwtModule {
8
8
  static forRoot(options: JwtVerifierOptions): ModuleType;
9
- static forRootAsync(options: AsyncModuleOptions<JwtVerifierOptions>): ModuleType;
9
+ static forRootAsync(options: AsyncModuleOptions<JwtVerifierOptions> & {
10
+ global?: boolean;
11
+ }): ModuleType;
10
12
  private static createModule;
11
13
  }
12
14
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAiC,MAAM,cAAc,CAAC;AAOhH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIrD,KAAK,UAAU,GAAG,WAAW,CAAC;AAyE9B;;GAEG;AACH,qBAAa,SAAS;IACpB,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,kBAAkB,GAAG,UAAU;IAQvD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,GAAG,UAAU;IAShF,OAAO,CAAC,MAAM,CAAC,YAAY;CAgB5B"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,kBAAkB,EAAE,KAAK,WAAW,EAAiC,MAAM,cAAc,CAAC;AAOhH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIrD,KAAK,UAAU,GAAG,WAAW,CAAC;AAyE9B;;GAEG;AACH,qBAAa,SAAS;IACpB,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,kBAAkB,GAAG,UAAU;IAQvD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,kBAAkB,CAAC,kBAAkB,CAAC,GAAG;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,UAAU;IASvG,OAAO,CAAC,MAAM,CAAC,YAAY;CAkB5B"}
package/dist/module.js CHANGED
@@ -64,7 +64,7 @@ export class JwtModule {
64
64
  provide: JWT_OPTIONS,
65
65
  scope: 'singleton',
66
66
  useValue: options
67
- }, Boolean(options.refreshToken), Boolean(options.refreshToken), 'singleton');
67
+ }, Boolean(options.refreshToken), Boolean(options.refreshToken), 'singleton', false, options.global ?? false);
68
68
  }
69
69
  static forRootAsync(options) {
70
70
  return this.createModule({
@@ -72,12 +72,13 @@ export class JwtModule {
72
72
  provide: JWT_OPTIONS,
73
73
  scope: 'singleton',
74
74
  useFactory: options.useFactory
75
- }, true, true, 'transient', true);
75
+ }, true, true, 'transient', true, options.global ?? false);
76
76
  }
77
- static createModule(optionsProvider, includeRefreshTokenProvider, includeRefreshTokenExport, refreshTokenServiceScope, deferRefreshTokenServiceRegistration = false) {
77
+ static createModule(optionsProvider, includeRefreshTokenProvider, includeRefreshTokenExport, refreshTokenServiceScope, deferRefreshTokenServiceRegistration = false, global = false) {
78
78
  class JwtRuntimeModule {}
79
79
  defineModuleMetadata(JwtRuntimeModule, {
80
80
  exports: [JwtService, DefaultJwtVerifier, DefaultJwtSigner, ...(includeRefreshTokenExport ? [RefreshTokenService] : [])],
81
+ global,
81
82
  providers: createJwtModuleProviders(optionsProvider, includeRefreshTokenProvider, refreshTokenServiceScope, deferRefreshTokenServiceRegistration)
82
83
  });
83
84
  return JwtRuntimeModule;
package/dist/types.d.ts CHANGED
@@ -21,6 +21,8 @@ export interface JwtVerifierOptions {
21
21
  accessTokenTtlSeconds?: number;
22
22
  audience?: string | string[];
23
23
  clockSkewSeconds?: number;
24
+ /** Whether JWT providers should be visible globally. Defaults to `false`. */
25
+ global?: boolean;
24
26
  issuer?: string;
25
27
  jwksCacheTtl?: number;
26
28
  jwksRequestTimeoutMs?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAEnH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACrH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACxD,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACzD;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACrD"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAEnH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACrH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,SAAU,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACxD,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACzD;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACrD"}
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "signing",
10
10
  "verification"
11
11
  ],
12
- "version": "1.0.0-beta.2",
12
+ "version": "1.0.0-beta.3",
13
13
  "private": false,
14
14
  "license": "MIT",
15
15
  "repository": {
@@ -36,9 +36,9 @@
36
36
  "dist"
37
37
  ],
38
38
  "dependencies": {
39
- "@fluojs/core": "^1.0.0-beta.2",
40
- "@fluojs/di": "^1.0.0-beta.4",
41
- "@fluojs/runtime": "^1.0.0-beta.4"
39
+ "@fluojs/core": "^1.0.0-beta.4",
40
+ "@fluojs/di": "^1.0.0-beta.6",
41
+ "@fluojs/runtime": "^1.0.0-beta.11"
42
42
  },
43
43
  "devDependencies": {
44
44
  "vitest": "^3.2.4"