Conversation
認証の自動リフレッシュ機能の基盤として、AuthState型に "refreshing"状態を追加し、TCNetConfigurationにautoReauth (デフォルトtrue)とreauthInterval(デフォルト60000ms)を追加する。
resetAuthSession + sendAuthSequenceの既存フローに合流する 再認証ロジックを実装する。single-flight保証付き。 executeReauthでresetAuthSession後にstate="refreshing"を設定し、 ユーザーが再認証中を観測可能にする。 handleAuthPacketのcmd=1受理条件にrefreshingを追加する。
認証成功後に自動再認証タイマーを起動する仕組みを追加する。 autoReauth=trueかつreauthInterval>=10000の場合のみ起動する。
手動で認証をリフレッシュするための公開APIを追加する。 single-flight保証付きで、進行中の再認証にはPromiseを共有する。
- executeReauthのonAuthから冗長な_authState代入を削除 テスト側でhandleAuthPacketの実フローを忠実にシミュレートする - startAutoReauthのsetIntervalにunref()を追加 disconnect忘れ時にプロセス終了をブロックしない
- T1 [Critical]: disconnectSocketsでreauthPromise進行中なら authFailedをemitしてPromiseを確実にrejectする - T2 [High]: executeReauthのcatchでリスナー・タイマーを cleanupしsendAuthSequence失敗時のリークを防止する - T3 [Medium]: executeReauth内のsetTimeoutにunref()を追加し disconnect後のプロセス終了ブロックを防止する - T4 [Low]: reauthInterval=10000の境界値テストを追加する - T5 [Low]: reauthFailedイベントの引数仕様をドキュメントに追記する
sendAuthSequenceはsessionToken===nullガードでresetAuthSessionを 呼び出すため、executeReauthで設定した"refreshing"状態が"none"に 上書きされていた。実機テストで以下の改善を確認: - "refreshing"状態が正しく観測可能になった - Bridgeのトークン再送が高速化(94s→2s) - 全再認証が成功(修正前は1/3のみ成功) BridgeはOptInブロードキャスト経由でトークンを再送するため、 resetAuthSessionによる状態リセットのみで再認証フローに合流できる。
🦋 Changeset detectedLatest commit: fb76ebb The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (1)
📜 Recent review details🧰 Additional context used🧠 Learnings (3)📚 Learning: 2026-04-08T12:28:35.362ZApplied to files:
📚 Learning: 2026-03-24T19:15:40.455ZApplied to files:
📚 Learning: 2026-03-21T05:30:31.035ZApplied to files:
🔇 Additional comments (6)
Summary by CodeRabbit
WalkthroughTCNASDPの自動再認証が追加され、認証状態に "refreshing" を導入。 Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant TCNet as TCNetClient
participant Timer as AutoReauthTimer
participant Bridge as Bridge
participant Events as AuthEvents
Note over TCNet: 初期認証成功
Client->>TCNet: authenticate()
TCNet->>TCNet: _authState = "authenticated"
TCNet->>Timer: startAutoReauth()
Timer->>Timer: setInterval(reauthInterval)
TCNet->>Events: emit authenticated
Note over TCNet: 自動再認証サイクル
loop Every reauthInterval
Timer->>TCNet: performReauth()
alt _authState == "authenticated" and no in-flight
TCNet->>TCNet: _authState = "refreshing"
TCNet->>Bridge: request token refresh
Bridge->>TCNet: AppData (cmd=1) with token
alt Token valid
TCNet->>TCNet: _authState = "authenticated"
TCNet->>Events: emit reauthenticated
else Token invalid / timeout
TCNet->>TCNet: _authState = "failed"
TCNet->>Events: emit reauthFailed (Error)
end
else Skip
Note over TCNet: 非認証または既存の in‑flight の場合はスキップ
end
end
Note over TCNet: 手動再認証
Client->>TCNet: reauth()
alt 条件成立 (authenticated & xtea configured)
TCNet->>TCNet: reuse or start executeReauth()
TCNet->>Events: emit reauthenticated / reauthFailed
else Error
TCNet-->>Client: Promise rejection
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces an automatic and manual re-authentication mechanism for TCNASDP sessions to maintain the 'LICENSE: EXT' state. Changes include a new 'refreshing' state, configuration options for auto-refresh intervals, and event emitters for re-authentication success or failure. Feedback focuses on improving the robustness of the reauth method by checking for existing promises before state validation, preserving the bridgeIsWindows cache during refreshes to avoid redundant OS detection, and documenting the minimum interval constraint for automatic re-authentication.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/tcnet.ts`:
- Around line 959-1004: The catch block in executeReauth redundantly calls
cleanup?.() even though doCleanup is already invoked by onAuth/onFail/timeout;
remove the redundant cleanup?.() invocation from the catch block to avoid
duplicate cleanup calls. Specifically, edit executeReauth to keep the cleanup
variable and doCleanup closure used by the authPromise listeners (onAuth,
onFail) and the timeout, but delete the extra cleanup?.() call inside the catch
where this.emit("reauthFailed", ...) and throw err remain; ensure
removeListener/clearTimeout are only performed via doCleanup.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 90a349b2-8321-445f-9c5b-925c599e49ca
📒 Files selected for processing (4)
docs/wiki/Implementation-Status.mdsrc/auth.tssrc/tcnet.tstests/auth.test.ts
📜 Review details
🔇 Additional comments (13)
src/auth.ts (1)
24-24: LGTM!
"refreshing"状態の追加は適切です。既存の消費者コードは通常"authenticated"や"failed"をチェックするため、後方互換性が維持されています。docs/wiki/Implementation-Status.md (1)
80-107: LGTM!ドキュメントは実装と一致しており、新しい認証状態、イベント、設定項目、APIの使用例が適切に記載されています。
tests/auth.test.ts (5)
271-288: LGTM!テストヘルパーメソッドは既存のパターンと一貫しており、再認証機能の内部状態へのアクセスを適切に提供しています。
455-496: LGTM!自動再認証タイマーの起動条件とタイマーの重複防止に関するテストが適切に実装されています。クリーンアップも正しく行われています。
869-941: LGTM!
performReauthのテストは主要なシナリオを網羅しています。single-flight保証、状態遷移、イベント発火のテストが適切に実装されています。
943-991: LGTM!タイマーのライフサイクルテストは境界値(9999/10000)を含め、起動・停止の動作を適切に検証しています。
993-1069: LGTM!公開API
reauth()のエラーケースと成功ケース、single-flight動作、およびdisconnect時のクリーンアップ動作のテストが適切に実装されています。src/tcnet.ts (6)
58-65: LGTM!設定項目のデフォルト値は適切です。
reauthInterval(60秒)はBridgeのタイムアウト(約100秒)より十分短く、実機テストで検証済みとのことで安心です。
253-258: LGTM!disconnect時のクリーンアップ順序が適切です。
authFailedを先に発火してからresetAuthSessionを呼ぶことで、進行中のreauthPromiseが確実にrejectされます。
914-933: LGTM!タイマー管理が適切に実装されています。重複防止ガード、
unref()によるプロセス終了への影響回避、最小間隔(10秒)の制限が適切です。
940-948: LGTM!single-flight保証が正しく実装されています。
reauthPromiseはfinallyブロックで確実にクリアされます。
1083-1086: LGTM!
"refreshing"状態の追加により、再認証中もBridgeからのトークン受信を正しく処理できます。sessionToken === nullのガードと組み合わせて安全です。
1141-1152: LGTM!公開API
reauth()は適切な事前条件チェックとsingle-flight保証を備えています。"refreshing"状態も許可することで、進行中の再認証Promiseを共有できます。
- reauth()でreauthPromiseチェックをstate チェックの前に移動し、 再認証中のpending状態でもPromiseを返せるようにする - reauthIntervalのJSDocに10000ms下限の制約を明記する - executeReauthでresetAuthSession()の代わりに必要な状態のみ 個別リセットしbridgeIsWindowsキャッシュを保持する
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/tcnet.ts`:
- Around line 1005-1008: catch ブロックで再認証失敗時に authenticationState が "refreshing"
のまま残っているので、cleanup 実行前に現在の bridgeIsWindows を保持しつつ this.authenticationState
を少なくとも "failed" に戻してください(handleAuthPacket が "failed"
を処理できるためこれで監視側の誤認を防げます)。その後で cleanup?.()、this.emit("reauthFailed", ...)、throw
err の順に続けるように修正してください。参照箇所: authenticationState, bridgeIsWindows,
handleAuthPacket, this.emit("reauthFailed", ...).
- Around line 915-925: startAutoReauth currently starts the interval without
re-checking the live connection/auth state, so add a guard at the start of
startAutoReauth to verify the instance is still connected/authenticated (e.g.
check this.connected / this.authenticated or call an existing
isConnected()/isAuthenticated() method) before creating reauthIntervalId; if the
connection is not active, do not set reauthIntervalId or call unref(); keep
existing checks for config.autoReauth and config.reauthInterval and ensure
performReauth is still invoked inside the interval when appropriate.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: bb185069-a642-4966-b78d-a24e2b368056
📒 Files selected for processing (2)
.changeset/auth-refresh.mdsrc/tcnet.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-04-08T12:28:35.362Z
Learnt from: 9c5s
Repo: 9c5s/node-tcnet PR: 63
File: src/tcnet.ts:960-1010
Timestamp: 2026-04-08T12:28:35.362Z
Learning: In `src/tcnet.ts` (node-tcnet, TypeScript), the `cleanup?.()` call in the catch block of `executeReauth` is intentionally kept as defensive programming. The maintainer (9c5s) prefers this pattern because `removeListener`/`clearTimeout` are idempotent, so the redundant call costs nothing and provides safety against future changes to the control flow.
Applied to files:
.changeset/auth-refresh.mdsrc/tcnet.ts
🔇 Additional comments (1)
src/tcnet.ts (1)
1147-1157: single-flight の入口順序はこのままで良いです
reauthPromiseを認証状態チェックより先に返しているので、"refreshing"遷移後の後続呼び出しも同じ Promise を共有できます。
- startAutoReauthに接続・認証状態ガードを追加 authenticatedリスナー内でdisconnect等が呼ばれた場合に 不要なタイマー起動を防止する - executeReauthのcatchでrefreshing状態をfailedに回復 タイムアウト等の失敗後にauthenticationStateが永遠に refreshingのまま残る問題を修正する
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/tcnet.ts`:
- Around line 952-959: The JSDoc for executeReauth() is incorrect: it says the
function rejoins the existing flow via resetAuthSession + sendAuthSequence, but
the implementation intentionally avoids calling resetAuthSession and
sendAuthSequence to preserve the refreshing state; update the JSDoc on
executeReauth() to describe the actual behavior (that it maintains the
refreshing flag, does not call resetAuthSession/sendAuthSequence, registers
listeners before triggering any remote response to avoid missed events, and
waits for authenticated/authFailed events or timeoutMs), and reference the
refreshing flag, resetAuthSession, sendAuthSequence, and executeReauth in the
description so future authors won't revert the current flow.
In `@tests/auth.test.ts`:
- Around line 1057-1070: The test must assert that the second call shares the
exact same Promise as the first (not just that both eventually resolve); update
the test around AuthTestClient and its callReauth() calls to add a strict
identity assertion (e.g., expect(p1).toBe(p2) or Object.is(p1, p2)) before
awaiting Promise.all, then keep the existing emission and await to ensure both
resolve. Ensure you reference the existing variables p1 and p2 from the test so
the identity check guarantees single-flight behavior.
- Around line 469-477: The failing negative tests never reach the auto-reauth
guard because other preconditions aren't set; update the tests using
AuthTestClient to explicitly satisfy all unrelated guards before testing the
target guard: set the client to connected (e.g., client.connected = true or call
a helper that marks it connected) and set authenticationState to "authenticated"
where needed, then set config.autoReauth = false and invoke
callHandleAuth(createErrorPacket(...)); for the other case (lines ~975-1000)
likewise ensure authenticationState === "authenticated" and connected is true so
only the autoReauth/reauthInterval behavior is being verified; use
getReauthIntervalId() to assert no timer started or clear any pre-set interval
IDs before the test.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 60c4473b-03b9-495d-94db-02990948f6a6
📒 Files selected for processing (2)
src/tcnet.tstests/auth.test.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2026-04-08T12:28:35.362Z
Learnt from: 9c5s
Repo: 9c5s/node-tcnet PR: 63
File: src/tcnet.ts:960-1010
Timestamp: 2026-04-08T12:28:35.362Z
Learning: In `src/tcnet.ts` (node-tcnet, TypeScript), the `cleanup?.()` call in the catch block of `executeReauth` is intentionally kept as defensive programming. The maintainer (9c5s) prefers this pattern because `removeListener`/`clearTimeout` are idempotent, so the redundant call costs nothing and provides safety against future changes to the control flow.
Applied to files:
src/tcnet.ts
📚 Learning: 2026-03-27T08:24:18.571Z
Learnt from: 9c5s
Repo: 9c5s/node-tcnet PR: 50
File: src/network.ts:1010-1024
Timestamp: 2026-03-27T08:24:18.571Z
Learning: In the `node-tcnet` repository (`src/network.ts`), `Buffer.allocUnsafe()` is never used — only `Buffer.alloc()` is used throughout the codebase. Reserved fields in packet `write()` methods do not need explicit zero-initialization because `Buffer.alloc()` always zero-initializes. Suggesting defensive zero-writes for reserved packet offsets is unnecessary (YAGNI) for this codebase.
Applied to files:
src/tcnet.ts
📚 Learning: 2026-03-24T19:15:40.455Z
Learnt from: 9c5s
Repo: 9c5s/node-tcnet PR: 41
File: src/utils.ts:94-94
Timestamp: 2026-03-24T19:15:40.455Z
Learning: In the `node-tcnet` repository (`src/utils.ts`), the project targets ES2022 + NodeNext and does not need to support Node.js 18.0.0. The temporary numeric `family` field (4/6) in `os.networkInterfaces()` introduced in Node.js 18.0.0 and fixed in 18.1.0 does not need to be handled. Suggesting numeric `family` handling for defensive programming is unnecessary for this project.
Applied to files:
src/tcnet.ts
📚 Learning: 2026-03-21T05:30:31.035Z
Learnt from: 9c5s
Repo: 9c5s/node-tcnet PR: 2
File: src/tcnet.ts:249-255
Timestamp: 2026-03-21T05:30:31.035Z
Learning: In `src/network.ts` of the `node-tcnet` repository: `TCNetDataPacket.read()` (class defined at line 321, read() at line 330) converts the wire-format 1-based layer to 0-based by doing `this.layer = this.buffer.readUInt8(25) - 1`. In contrast, `TCNetRequestPacket.read()` (class defined at line 225, read() at line 231) does NOT subtract 1: `this.layer = this.buffer.readUInt8(25)`. Therefore, `dataPacket.layer` from a received `TCNetDataPacket` is already 0-based and correctly matches the 0-based key stored in `requestData()`. Flagging a missing `-1` in `TCNetDataPacket.read()` is a false positive.
Applied to files:
src/tcnet.ts
- executeReauthのJSDocを実装に合わせて更新する (resetAuthSession/sendAuthSequenceを呼ばない設計の説明) - 否定系テストで意図したガード以外の前提条件を満たすよう修正 (connected/authState設定を追加し、対象ガードのみ検証)
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tests/auth.test.ts`:
- Around line 898-912: The test comment is inaccurate: the early return in
performReauth can be caused by this.reauthPromise being set and/or
this._authState transitioning to "refreshing"; update the test comment in the
"single-flight: reauthPromiseが存在する間は2回目がskipされる" case to state that the second
call is skipped because performReauth sets this.reauthPromise (and the client’s
_authState becomes "refreshing"), or make the test deterministic by explicitly
asserting which condition (reauthPromise vs _authState) is responsible;
reference AuthTestClient, callPerformReauth, performReauth, reauthPromise and
_authState when modifying the comment or test assertions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: e603a312-81ac-4763-82a3-9b79f487f556
📒 Files selected for processing (2)
src/tcnet.tstests/auth.test.ts
📜 Review details
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2026-04-08T12:28:35.362Z
Learnt from: 9c5s
Repo: 9c5s/node-tcnet PR: 63
File: src/tcnet.ts:960-1010
Timestamp: 2026-04-08T12:28:35.362Z
Learning: In `src/tcnet.ts` (node-tcnet, TypeScript), the `cleanup?.()` call in the catch block of `executeReauth` is intentionally kept as defensive programming. The maintainer (9c5s) prefers this pattern because `removeListener`/`clearTimeout` are idempotent, so the redundant call costs nothing and provides safety against future changes to the control flow.
Applied to files:
tests/auth.test.tssrc/tcnet.ts
📚 Learning: 2026-03-27T08:24:18.571Z
Learnt from: 9c5s
Repo: 9c5s/node-tcnet PR: 50
File: src/network.ts:1010-1024
Timestamp: 2026-03-27T08:24:18.571Z
Learning: In the `node-tcnet` repository (`src/network.ts`), `Buffer.allocUnsafe()` is never used — only `Buffer.alloc()` is used throughout the codebase. Reserved fields in packet `write()` methods do not need explicit zero-initialization because `Buffer.alloc()` always zero-initializes. Suggesting defensive zero-writes for reserved packet offsets is unnecessary (YAGNI) for this codebase.
Applied to files:
src/tcnet.ts
📚 Learning: 2026-03-24T19:15:40.455Z
Learnt from: 9c5s
Repo: 9c5s/node-tcnet PR: 41
File: src/utils.ts:94-94
Timestamp: 2026-03-24T19:15:40.455Z
Learning: In the `node-tcnet` repository (`src/utils.ts`), the project targets ES2022 + NodeNext and does not need to support Node.js 18.0.0. The temporary numeric `family` field (4/6) in `os.networkInterfaces()` introduced in Node.js 18.0.0 and fixed in 18.1.0 does not need to be handled. Suggesting numeric `family` handling for defensive programming is unnecessary for this project.
Applied to files:
src/tcnet.ts
📚 Learning: 2026-03-21T05:30:31.035Z
Learnt from: 9c5s
Repo: 9c5s/node-tcnet PR: 2
File: src/tcnet.ts:249-255
Timestamp: 2026-03-21T05:30:31.035Z
Learning: In `src/network.ts` of the `node-tcnet` repository: `TCNetDataPacket.read()` (class defined at line 321, read() at line 330) converts the wire-format 1-based layer to 0-based by doing `this.layer = this.buffer.readUInt8(25) - 1`. In contrast, `TCNetRequestPacket.read()` (class defined at line 225, read() at line 231) does NOT subtract 1: `this.layer = this.buffer.readUInt8(25)`. Therefore, `dataPacket.layer` from a received `TCNetDataPacket` is already 0-based and correctly matches the 0-based key stored in `requestData()`. Flagging a missing `-1` in `TCNetDataPacket.read()` is a false positive.
Applied to files:
src/tcnet.ts
🔇 Additional comments (12)
tests/auth.test.ts (5)
1063-1076: テストは正しく動作しています過去レビューで
expect(p2).toBe(p1)の追加が提案されましたが、実際にはこのアサーションは失敗します。理由:
reauth()はasync関数なので、常に新しいPromiseを返すp1はperformReauth()から返されるPromisep2はthis.reauthPromiseをreturnするが、async関数なので新しいPromiseでラップされる- したがって
p1 !== p2(オブジェクト参照は異なる)現在のテストは両方のPromiseが正常に解決することを検証しており、single-flight動作(1つの認証操作のみが実行される)を正しくテストしています。コメントの「両方同じPromiseを共有する」は「同じ認証操作を共有する」という意味で理解すべきです。
271-288: LGTM!テストヘルパーメソッドの追加により、privateメンバーへのアクセスが適切にカプセル化されています。
src/tcnet.tsのprivateメンバー名(reauthPromise,reauthIntervalId,_authState等)と一致しています。
455-499: LGTM!初回認証成功時のautoReauthタイマー起動テストが適切です:
connectedとauthStateの前提条件を設定(過去レビューで対応済み)- タイマーの起動/非起動を検証
- 重複呼び出し時のタイマー一意性を検証
- テスト後のクリーンアップ(
callStopAutoReauth)も行われています
963-1033: LGTM!
startAutoReauth/stopAutoReauthのテストが網羅的です:
- 正常起動のテスト
- 各ガード条件(未接続、autoReauth=false、reauthInterval下限)のテスト
- 下限ちょうど(10000ms)での起動確認
- 停止後のintervalIdクリア確認
1079-1113: LGTM!disconnect時のreauthクリーンアップテストが
disconnectSocketsの実フローを正しく再現しています:
stopAutoReauth()でタイマー停止reauthPromise存在時にauthFailedをemitresetAuthSession()でセッションリセットin-flight promiseのrejectとreauthPromiseのクリアを検証しています。
src/tcnet.ts (7)
13-13: LGTM!
AUTH_REFRESH_TIMEOUT = 100_000(100秒) はBridgeの認証タイムアウト(約100秒)に対応しており、適切な値です。
58-66: LGTM!設定オプションの追加は適切です。JSDocに10000ms未満の制限とデフォルト値の理由が明記されており、実機テストで実証された値を使用しています。
254-259: LGTM!
disconnectSocketsでのreauthクリーンアップロジックは適切です:
stopAutoReauth()でタイマーを先に停止reauthPromiseが進行中の場合はauthFailedをemitしてPromiseをreject可能にする- その後
resetAuthSession()で認証状態をリセットこの順序により、in-flightのreauthPromiseが確実にrejectされます。
915-927: LGTM!
startAutoReauthのガード条件が正しく実装されています:
!this.connected || this._authState !== "authenticated"で接続・認証状態を確認(過去レビューで対応済み)!this.config.autoReauth || this.config.reauthInterval < 10_000で設定値を確認this.reauthIntervalIdで重複タイマー防止unref()でNode.jsプロセスの終了を妨げない
937-950: LGTM!
performReauthのsingle-flight実装が正しいです:
_authState !== "authenticated" || this.reauthPromiseで二重実行を防止finallyブロックでreauthPromiseを確実にクリア
952-1018: LGTM!
executeReauthの実装が適切です:
- JSDocが実装に合わせて更新されている(過去レビューで対応済み)
bridgeIsWindowsキャッシュを保持して毎回のOS判定pingを回避refreshing状態に遷移し、Bridgeからのtoken再送を待つ設計- 失敗時は
_authStateをfailedに戻して自然回復を可能にする(過去レビューで対応済み)cleanup?.()はremoveListener/clearTimeoutの冪等性により防御的プログラミングとして意図的に保持(learning)
1146-1166: LGTM!公開API
reauth()の実装が適切です:
xteaCiphertextの検証- 進行中の
reauthPromiseがある場合はそれを返す(single-flight)- 認証状態の検証
performReauth()への委譲
Summary
Bridgeの認証タイムアウト(~100秒)を回避するため、TCNASDP認証シーケンスを定期的に再実行してLICENSE: EXTを維持する自動リフレッシュ機能を実装する。
AuthState型に"refreshing"を追加し、再認証中の状態を観測可能にするautoReauth/reauthInterval設定と公開reauth()メソッドを追加する主な変更
src/auth.tsAuthState型に"refreshing"追加src/tcnet.tstests/auth.test.tsdocs/wiki/Implementation-Status.md設計判断
sendAuthSequenceを呼ばない:executeReauthではresetAuthSessionのみ実行し、BridgeがOptInブロードキャスト経由でトークンを再送するのを待つ。sendAuthSequenceはsessionToken===nullガードでresetAuthSessionを再呼出しして"refreshing"状態を上書きするため不使用setInterval.unref(): disconnect忘れ時にプロセス終了をブロックしないauthFailedemit:reauthPromise進行中にdisconnectした場合、resetAuthSessionはauthFailedをemitしないため、明示的にemitしてPromiseを確実にrejectする実機テスト結果 (Bridge 3.5 @ 192.168.0.10, 240秒間)
Test plan
npx vitest run --project unit)npx tsgo --noEmit)npm run lint:ts)npm run build)