Skip to content

Commit 916afb5

Browse files
authored
refactor(account): share token freshness helper (#20591)
1 parent 5daf2fa commit 916afb5

File tree

2 files changed

+13
-6
lines changed

2 files changed

+13
-6
lines changed

packages/opencode/src/account/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ class TokenRefreshRequest extends Schema.Class<TokenRefreshRequest>("TokenRefres
120120

121121
const clientId = "opencode-cli"
122122
const eagerRefreshThreshold = Duration.minutes(5)
123+
const eagerRefreshThresholdMs = Duration.toMillis(eagerRefreshThreshold)
124+
125+
const isTokenFresh = (tokenExpiry: number | null, now: number) =>
126+
tokenExpiry != null && tokenExpiry > now + eagerRefreshThresholdMs
123127

124128
const mapAccountServiceError =
125129
(message = "Account service operation failed") =>
@@ -219,7 +223,7 @@ export namespace Account {
219223

220224
const account = maybeAccount.value
221225
const now = yield* Clock.currentTimeMillis
222-
if (account.token_expiry && account.token_expiry > now + Duration.toMillis(eagerRefreshThreshold)) {
226+
if (isTokenFresh(account.token_expiry, now)) {
223227
return account.access_token
224228
}
225229

@@ -229,7 +233,7 @@ export namespace Account {
229233

230234
const resolveToken = Effect.fnUntraced(function* (row: AccountRow) {
231235
const now = yield* Clock.currentTimeMillis
232-
if (row.token_expiry && row.token_expiry > now + Duration.toMillis(eagerRefreshThreshold)) {
236+
if (isTokenFresh(row.token_expiry, now)) {
233237
return row.access_token
234238
}
235239

packages/opencode/test/account/service.test.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ const truncate = Layer.effectDiscard(
1818

1919
const it = testEffect(Layer.merge(AccountRepo.layer, truncate))
2020

21+
const insideEagerRefreshWindow = Duration.toMillis(Duration.minutes(1))
22+
const outsideEagerRefreshWindow = Duration.toMillis(Duration.minutes(10))
23+
2124
const live = (client: HttpClient.HttpClient) =>
2225
Account.layer.pipe(Layer.provide(Layer.succeed(HttpClient.HttpClient, client)))
2326

@@ -63,7 +66,7 @@ it.live("orgsByAccount groups orgs per account", () =>
6366
url: "https://one.example.com",
6467
accessToken: AccessToken.make("at_1"),
6568
refreshToken: RefreshToken.make("rt_1"),
66-
expiry: Date.now() + 10 * 60_000,
69+
expiry: Date.now() + outsideEagerRefreshWindow,
6770
orgID: Option.none(),
6871
}),
6972
)
@@ -75,7 +78,7 @@ it.live("orgsByAccount groups orgs per account", () =>
7578
url: "https://two.example.com",
7679
accessToken: AccessToken.make("at_2"),
7780
refreshToken: RefreshToken.make("rt_2"),
78-
expiry: Date.now() + 10 * 60_000,
81+
expiry: Date.now() + outsideEagerRefreshWindow,
7982
orgID: Option.none(),
8083
}),
8184
)
@@ -159,7 +162,7 @@ it.live("token refreshes before expiry when inside the eager refresh window", ()
159162
url: "https://one.example.com",
160163
accessToken: AccessToken.make("at_old"),
161164
refreshToken: RefreshToken.make("rt_old"),
162-
expiry: Date.now() + 60_000,
165+
expiry: Date.now() + insideEagerRefreshWindow,
163166
orgID: Option.none(),
164167
}),
165168
)
@@ -267,7 +270,7 @@ it.live("config sends the selected org header", () =>
267270
url: "https://one.example.com",
268271
accessToken: AccessToken.make("at_1"),
269272
refreshToken: RefreshToken.make("rt_1"),
270-
expiry: Date.now() + 10 * 60_000,
273+
expiry: Date.now() + outsideEagerRefreshWindow,
271274
orgID: Option.none(),
272275
}),
273276
)

0 commit comments

Comments
 (0)