refactor(account): share token freshness helper (#20591)
parent
5daf2fa7f0
commit
916afb5220
|
|
@ -120,6 +120,10 @@ class TokenRefreshRequest extends Schema.Class<TokenRefreshRequest>("TokenRefres
|
|||
|
||||
const clientId = "opencode-cli"
|
||||
const eagerRefreshThreshold = Duration.minutes(5)
|
||||
const eagerRefreshThresholdMs = Duration.toMillis(eagerRefreshThreshold)
|
||||
|
||||
const isTokenFresh = (tokenExpiry: number | null, now: number) =>
|
||||
tokenExpiry != null && tokenExpiry > now + eagerRefreshThresholdMs
|
||||
|
||||
const mapAccountServiceError =
|
||||
(message = "Account service operation failed") =>
|
||||
|
|
@ -219,7 +223,7 @@ export namespace Account {
|
|||
|
||||
const account = maybeAccount.value
|
||||
const now = yield* Clock.currentTimeMillis
|
||||
if (account.token_expiry && account.token_expiry > now + Duration.toMillis(eagerRefreshThreshold)) {
|
||||
if (isTokenFresh(account.token_expiry, now)) {
|
||||
return account.access_token
|
||||
}
|
||||
|
||||
|
|
@ -229,7 +233,7 @@ export namespace Account {
|
|||
|
||||
const resolveToken = Effect.fnUntraced(function* (row: AccountRow) {
|
||||
const now = yield* Clock.currentTimeMillis
|
||||
if (row.token_expiry && row.token_expiry > now + Duration.toMillis(eagerRefreshThreshold)) {
|
||||
if (isTokenFresh(row.token_expiry, now)) {
|
||||
return row.access_token
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,9 @@ const truncate = Layer.effectDiscard(
|
|||
|
||||
const it = testEffect(Layer.merge(AccountRepo.layer, truncate))
|
||||
|
||||
const insideEagerRefreshWindow = Duration.toMillis(Duration.minutes(1))
|
||||
const outsideEagerRefreshWindow = Duration.toMillis(Duration.minutes(10))
|
||||
|
||||
const live = (client: HttpClient.HttpClient) =>
|
||||
Account.layer.pipe(Layer.provide(Layer.succeed(HttpClient.HttpClient, client)))
|
||||
|
||||
|
|
@ -63,7 +66,7 @@ it.live("orgsByAccount groups orgs per account", () =>
|
|||
url: "https://one.example.com",
|
||||
accessToken: AccessToken.make("at_1"),
|
||||
refreshToken: RefreshToken.make("rt_1"),
|
||||
expiry: Date.now() + 10 * 60_000,
|
||||
expiry: Date.now() + outsideEagerRefreshWindow,
|
||||
orgID: Option.none(),
|
||||
}),
|
||||
)
|
||||
|
|
@ -75,7 +78,7 @@ it.live("orgsByAccount groups orgs per account", () =>
|
|||
url: "https://two.example.com",
|
||||
accessToken: AccessToken.make("at_2"),
|
||||
refreshToken: RefreshToken.make("rt_2"),
|
||||
expiry: Date.now() + 10 * 60_000,
|
||||
expiry: Date.now() + outsideEagerRefreshWindow,
|
||||
orgID: Option.none(),
|
||||
}),
|
||||
)
|
||||
|
|
@ -159,7 +162,7 @@ it.live("token refreshes before expiry when inside the eager refresh window", ()
|
|||
url: "https://one.example.com",
|
||||
accessToken: AccessToken.make("at_old"),
|
||||
refreshToken: RefreshToken.make("rt_old"),
|
||||
expiry: Date.now() + 60_000,
|
||||
expiry: Date.now() + insideEagerRefreshWindow,
|
||||
orgID: Option.none(),
|
||||
}),
|
||||
)
|
||||
|
|
@ -267,7 +270,7 @@ it.live("config sends the selected org header", () =>
|
|||
url: "https://one.example.com",
|
||||
accessToken: AccessToken.make("at_1"),
|
||||
refreshToken: RefreshToken.make("rt_1"),
|
||||
expiry: Date.now() + 10 * 60_000,
|
||||
expiry: Date.now() + outsideEagerRefreshWindow,
|
||||
orgID: Option.none(),
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue