Skip to content

Commit 96ede30

Browse files
authored
Merge pull request #98 from geolonia/feat/proactive-token-refresh
fix: token+apiKey 共存時のセッション切れを修正
2 parents 36f97e9 + 50fd90f commit 96ede30

5 files changed

Lines changed: 390 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@
77

88
## [Unreleased]
99

10+
## [0.10.1] - 2026-04-05
11+
12+
### 2026-04-05
13+
- **Fix**: token と apiKey が config に共存する場合、`canRefresh()` が apiKey の存在でリフレッシュをブロックし、JWT 期限切れ後にセッションが復旧不能になる問題を修正 (#98)
14+
- **Feat**: リクエスト前に JWT の `exp` を確認し、期限切れ/期限間近なら事前にリフレッシュするプロアクティブ・トークンリフレッシュを追加 (#98)
15+
1016
## [0.10.0] - 2026-04-03
1117

1218
### 2026-04-03
@@ -176,7 +182,8 @@
176182
### 2026-02-26
177183
- **Docs**: README にインストール手順・使い方・コマンドリファレンスを追加 (#1)
178184

179-
[Unreleased]: https://github.com/geolonia/geonicdb-cli/compare/v0.10.0...HEAD
185+
[Unreleased]: https://github.com/geolonia/geonicdb-cli/compare/v0.10.1...HEAD
186+
[0.10.1]: https://github.com/geolonia/geonicdb-cli/compare/v0.10.0...v0.10.1
180187
[0.10.0]: https://github.com/geolonia/geonicdb-cli/compare/v0.9.0...v0.10.0
181188
[0.9.0]: https://github.com/geolonia/geonicdb-cli/compare/v0.8.0...v0.9.0
182189
[0.8.0]: https://github.com/geolonia/geonicdb-cli/compare/v0.7.0...v0.8.0

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@geolonia/geonicdb-cli",
3-
"version": "0.10.0",
3+
"version": "0.10.1",
44
"description": "A CLI client for the GeonicDB",
55
"type": "module",
66
"bin": {

src/client.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { ClientOptions, ClientResponse, NgsiError } from "./types.js";
22
import { clientCredentialsGrant } from "./oauth.js";
3+
import { getTokenStatus } from "./token.js";
34

45
export class DryRunSignal extends Error {
56
constructor() {
@@ -163,7 +164,19 @@ export class GdbClient {
163164
}
164165

165166
private canRefresh(): boolean {
166-
return (!!this.refreshToken || (!!this.clientId && !!this.clientSecret)) && !this.apiKey;
167+
if (!this.refreshToken && !(this.clientId && this.clientSecret)) return false;
168+
// When authenticating solely via apiKey (no token), token refresh is unnecessary
169+
if (!this.token && this.apiKey) return false;
170+
return true;
171+
}
172+
173+
/** Proactively refresh the token before making a request if it is expired or about to expire. */
174+
private async proactiveRefresh(): Promise<void> {
175+
if (!this.token || !this.canRefresh()) return;
176+
const status = getTokenStatus(this.token);
177+
if (status.isExpired || status.isExpiringSoon) {
178+
await this.performTokenRefresh();
179+
}
167180
}
168181

169182
/** Check whether an error indicates an authentication/token problem that may be resolved by refreshing. */
@@ -341,6 +354,7 @@ export class GdbClient {
341354
headers?: Record<string, string>;
342355
},
343356
): Promise<ClientResponse<T>> {
357+
await this.proactiveRefresh();
344358
try {
345359
return await this.executeRequest<T>(method, path, options);
346360
} catch (err) {
@@ -404,6 +418,7 @@ export class GdbClient {
404418
skipTenantHeader?: boolean;
405419
},
406420
): Promise<ClientResponse<T>> {
421+
await this.proactiveRefresh();
407422
try {
408423
return await this.executeRawRequest<T>(method, path, options);
409424
} catch (err) {

0 commit comments

Comments
 (0)