@ethlete/query 6.0.0-next.42 → 6.0.0-next.43

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @ethlete/query
2
2
 
3
+ ## 6.0.0-next.43
4
+
5
+ ### Patch Changes
6
+
7
+ - [#3075](https://github.com/ethlete-io/ethdk/pull/3075) [`48488fb`](https://github.com/ethlete-io/ethdk/commit/48488fbdc0d61bafe5e8117844e5efa2c31c330a) Thanks [@github-actions](https://github.com/apps/github-actions)! - Auth: a rejected cookie auto-login now ends the session through `onRefreshFailure` with `sessionEndCause()` `'expired'`, and `setTokens()` supersedes an auto-login still in flight so its late `401` no longer overwrites the seeded session.
8
+
9
+ - [`a533863`](https://github.com/ethlete-io/ethdk/commit/a533863ce73cbb9e3454b6016be39487aa965c7a) Thanks [@TomTomB](https://github.com/TomTomB)! - Query devtools: a session that ends as expired is dropped from the auth vault, so a tab seeded with it no longer meets the same dead token on every reload.
10
+
11
+ - [#3075](https://github.com/ethlete-io/ethdk/pull/3075) [`1d38e7e`](https://github.com/ethlete-io/ethdk/commit/1d38e7e0a025769f065d8ca7d506cb75ad89139a) Thanks [@github-actions](https://github.com/apps/github-actions)! - `et update` moves the `@ethlete/*` packages to a newer version, runs the codemods those versions
12
+ declare in their own `migrations.json`, and reports what needs a decision or an agent.
13
+
14
+ - [#3075](https://github.com/ethlete-io/ethdk/pull/3075) [`f9fbd3a`](https://github.com/ethlete-io/ethdk/commit/f9fbd3a6959a99af7c6de60d7ceaf2781e8a58d2) Thanks [@github-actions](https://github.com/apps/github-actions)! - Re-export types explicitly with `export type` so the barrels type-check under `isolatedModules`.
15
+
3
16
  ## 6.0.0-next.42
4
17
 
5
18
  ### Minor Changes
@@ -5279,6 +5279,10 @@ const createBearerAuthProviderImpl = (config) => {
5279
5279
  // executionState (e.g. `{ type: 'login', state: 'success' }`) via setupBearerQueryRegistry's
5280
5280
  // execute(), so that internal path calls applyTokens directly to avoid stomping it with this.
5281
5281
  const setTokens = (access, refresh) => {
5282
+ // A seed supersedes what is in flight, the way a logout does: the tokens are here, so a cookie
5283
+ // auto-login or a refresh still out with an older token can only report a failure that no longer
5284
+ // means anything - or apply the pair it comes back with over this one.
5285
+ invalidateTokenIssuingExecutions();
5282
5286
  applyTokens(access, refresh);
5283
5287
  executionState.set({ type: 'tokenSeed', state: 'success' });
5284
5288
  };
@@ -5339,6 +5343,7 @@ const createBearerAuthProviderImpl = (config) => {
5339
5343
  logout,
5340
5344
  afterTokenRefresh$,
5341
5345
  queries: queries,
5346
+ latestExecutedQuery: latestExecutedQuery.asReadonly(),
5342
5347
  executionState: executionState.asReadonly(),
5343
5348
  hasTokenIssuingExecutionInFlight,
5344
5349
  };
@@ -5804,7 +5809,18 @@ const withRefreshQuery = (key, config) => {
5804
5809
  });
5805
5810
  effect(() => {
5806
5811
  const state = context.executionState();
5807
- if (state?.type !== 'tokenRefresh' || state.state !== 'error')
5812
+ if (state?.state !== 'error')
5813
+ return;
5814
+ // `withPersistentAuth` spends the cookie's refresh token through this very query, and that
5815
+ // execution reports as `autoLogin` rather than as `tokenRefresh`. Judged by its type alone it
5816
+ // would end nothing: the tab keeps a rejected cookie's error state for good, `sessionEndCause`
5817
+ // never says `expired`, and an app gated on either never leaves its startup screen. The token
5818
+ // check keeps a session another tab handed over mid-request out of it - that session is not
5819
+ // this restore's to end.
5820
+ const isRejectedRestore = state.type === 'autoLogin' &&
5821
+ untracked(context.latestExecutedQuery)?.key === key &&
5822
+ !untracked(context.accessToken);
5823
+ if (state.type !== 'tokenRefresh' && !isRejectedRestore)
5808
5824
  return;
5809
5825
  onRefreshFailure({ error: state.error, logout: () => context.logout('expired') });
5810
5826
  });
@@ -8099,9 +8115,12 @@ const trackQueryDevtoolsAuthProvider = (registration) => {
8099
8115
  const stop = effect(() => {
8100
8116
  const accessToken = handle.accessToken();
8101
8117
  const refreshToken = handle.refreshToken();
8118
+ const endCause = handle.sessionEndCause();
8102
8119
  untracked(() => {
8103
8120
  if (accessToken && refreshToken)
8104
8121
  remember({ provider: name, accessToken, refreshToken });
8122
+ else if (endCause === 'expired')
8123
+ forgetExpired(name);
8105
8124
  else
8106
8125
  forgetActive(name);
8107
8126
  });
@@ -8212,6 +8231,26 @@ const forgetActive = (provider) => {
8212
8231
  persist();
8213
8232
  syncPill();
8214
8233
  };
8234
+ /**
8235
+ * Drops the session a provider was on because it expired, tokens and all - unlike every other way a
8236
+ * session ends, this pair is spent. Keeping it offers a switch back that can only fail, and a tab-local
8237
+ * seed would re-apply it on every reload, so the tab meets the same dead token until someone clears the
8238
+ * storage by hand.
8239
+ */
8240
+ const forgetExpired = (provider) => {
8241
+ const sessionId = active()[provider] ?? null;
8242
+ const { [provider]: _dropped, ...seeds } = readSeeds();
8243
+ writeSeeds(seeds);
8244
+ if (!sessionId)
8245
+ return;
8246
+ store.update((current) => ({
8247
+ ...current,
8248
+ sessions: current.sessions.filter((session) => session.id !== sessionId),
8249
+ }));
8250
+ setActive(provider, null);
8251
+ persist();
8252
+ syncPill();
8253
+ };
8215
8254
  /** The sessions offered for one provider, which are the ones this backend issued. */
8216
8255
  const queryDevtoolsAuthSessionsFor = (provider) => {
8217
8256
  const scope = scopeOf();
@@ -9582,7 +9621,7 @@ const armQueryDevtoolsOverrideTransfer = (recorder, ops) => {
9582
9621
 
9583
9622
  // Generated from package.json by tools/scripts/generate-version.js - do not edit.
9584
9623
  /** The version of `@ethlete/query` this build was cut from. */
9585
- const QUERY_VERSION = '6.0.0-next.42';
9624
+ const QUERY_VERSION = '6.0.0-next.43';
9586
9625
 
9587
9626
  /** How deep a schema is expanded before a nested branch is given up on. */
9588
9627
  const MAX_DEPTH = 12;