# refactor(auth): dedup cell login refresh + tidy jurisdiction test per cleanup review

`d9e0a5f`→[main](/content/gh/entireio/cli/commits/main/index.html)·

jagregory·4d ago·2 files·+30 added/-38 removed

- Extract refreshCellLoginJWT, shared by resolveActiveContextCellSubject
  and resolveStoredCellSubject (was a duplicated ~12-line build-provider →
  call → map-ErrNotLoggedIn block).
- Use the existing writeActiveContext test helper for the single-context
  TestJurisdictionToken_StoredContext seed.
- Drop the orphaned/stale doc-comment block left stacked above
  TestJurisdictionToken_StoredContext.

Behavior unchanged; fmt + lint clean, tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

## Sessions

01KXDCZ2NFPYHZEFQ56T24GHTYView transcript

## Changes

2

- cmd/entire/cli/auth
  
  - Mcell_data_api.go+27/-29
  
  - Mcell_data_api_test.go+3/-9

```
16 unmodified lines

17
18
19
20
21
22
23
276 unmodified lines

300
301
302
302
303
304
305
303
304
305
306
309
310
311
312
313
314
315
316
317
307
308
309
33 unmodified lines

343
344
345
357
358
359
360
361
362
346
347
348
349
350
367
368
369
370
371
372
373
374
375
376
351
352
353
2 unmodified lines

356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385

16 unmodified lines

"github.com/entireio/cli/cmd/entire/cli/api"
	"github.com/entireio/cli/internal/entireclient/clusterdiscovery"
	"github.com/entireio/cli/internal/entireclient/contexts"
	"github.com/entireio/cli/internal/entireclient/httputil"
	"github.com/entireio/cli/internal/entireclient/userdirs"
)
276 unmodified lines

return cellSubject{}, fmt.Errorf("not logged in (run 'entire login' first): %w", ErrNotLoggedIn)
	}

// Gate the login provider's HTTPS relaxation on the context's own core plus
	// the explicit --insecure-http-auth opt-in, mirroring resolveStoredCellSubject.
	allowInsecure := insecureHTTPEnabled() || isLoopbackHTTP(c.CoreURL)
	loginProvider, err := NewRefreshingLoginProvider(c, cellExchangeTransportForTest, allowInsecure)
	loginJWT, err := refreshCellLoginJWT(ctx, c)
	if err != nil {
		return cellSubject{}, err
	}
	loginJWT, err := loginProvider(ctx)
	if err != nil {
		if errors.Is(err, ErrNotLoggedIn) {
			return cellSubject{}, fmt.Errorf("not logged in (run 'entire login' first): %w", err)
		}
		// The provider already prefixes "refresh login token:"; return as-is to
		// avoid a doubled prefix.
		return cellSubject{}, err
	}

origin := api.OriginOnly(c.CoreURL)
	return cellSubject{
33 unmodified lines

return cellSubject{}, err
	}

// Gate the login provider's HTTPS relaxation on the core it actually dials
	// (selected.CoreURL) plus the explicit --insecure-http-auth opt-in, matching
	// the sibling ResolveDataAPIToken. A loopback data API must not relax HTTPS
	// for a non-loopback core.
	allowInsecure := insecureHTTPEnabled() || isLoopbackHTTP(selected.CoreURL)
	loginProvider, err := NewRefreshingLoginProvider(selected, cellExchangeTransportForTest, allowInsecure)
	loginJWT, err := refreshCellLoginJWT(ctx, selected)
	if err != nil {
		return cellSubject{}, err
	}

loginJWT, err := loginProvider(ctx)
	if err != nil {
		if errors.Is(err, ErrNotLoggedIn) {
			return cellSubject{}, fmt.Errorf("not logged in (run 'entire login' first): %w", err)
		}
		// The provider already prefixes "refresh login token:"; return as-is to
		// avoid a doubled prefix.
		return cellSubject{}, err
	}

return cellSubject{
		loginJWT:       loginJWT,
		discoveredCore: selected.CoreURL,
2 unmodified lines

}, nil
}

// refreshCellLoginJWT returns c's login JWT, transparently re-minting it from the
// stored refresh token. Shared by the active-context and discovered-context cell
// subject resolvers, which differ only in how they pick c.
func refreshCellLoginJWT(ctx context.Context, c *contexts.Context) (string, error) {
	// Gate the login provider's HTTPS relaxation on the core it actually dials
	// plus the explicit --insecure-http-auth opt-in: a loopback core must not
	// relax HTTPS for a non-loopback one.
	allowInsecure := insecureHTTPEnabled() || isLoopbackHTTP(c.CoreURL)
	loginProvider, err := NewRefreshingLoginProvider(c, cellExchangeTransportForTest, allowInsecure)
	if err != nil {
		return "", err
	}
	loginJWT, err := loginProvider(ctx)
	if err != nil {
		if errors.Is(err, ErrNotLoggedIn) {
			return "", fmt.Errorf("not logged in (run 'entire login' first): %w", err)
		}
		// The provider already prefixes "refresh login token:"; return as-is to
		// avoid a doubled prefix.
		return "", err
	}
	return loginJWT, nil
}

// resolveEnvTokenCellSubject builds the exchange subject from ENTIRE_TOKEN: the
// env token is the subject login JWT and its aud core is the environment signal
// (passed as dataOrigin) so the audience/core templates follow prod/staging/
``

Mcmd/entire/cli/auth/cell_data_api.go+27/-29

```

422 unmodified lines

423
424
425
426
427
428
429
426
427
428
429
434
430
431
432
433
434
9 unmodified lines

444
445
446
450
451
452
453
447
448
449
450

422 unmodified lines

}

// TestJurisdictionToken_StoredContext exercises the exported token-only path off
// a stored login context: it must return the exchanged identity token and mint
// it with scope=openid, the jurisdiction audience, and the login JWT as
// subject_token. Not parallel: manipulates env + token store.
// TestJurisdictionToken_StoredContext proves the stored path mints from the
// ACTIVE login context (like plain `entire auth token`), deriving the
// environment from that context's core rather than the data host. No
// ENTIRE_API_BASE_URL is set, so the default (entire.io) data host must NOT
// influence the result — only the active context does.
// influence the result — only the active context does. Not parallel: manipulates
// env + token store.
func TestJurisdictionToken_StoredContext(t *testing.T) {
	configDir := t.TempDir()
	t.Setenv("ENTIRE_CONFIG_DIR", configDir)
9 unmodified lines

if err := tokenstore.Set(svc, "me", tokenstore.EncodeTokenWithExpiration(loginJWT, 7200)); err != nil {
		t.Fatalf("seed token: %v", err)
	}
	ctxObj := &contexts.Context{Name: "me@entire", CoreURL: core, Handle: "me", KeychainService: svc}
	if err := contexts.Save(configDir, &contexts.File{CurrentContext: ctxObj.Name, Contexts: []*contexts.Context{ctxObj}}); err != nil {
		t.Fatalf("save contexts: %v", err)
	}
	writeActiveContext(t, configDir, "me@entire", core, "me", svc)

ct := &captureTransport{token: "cell-identity-token"}
	t.Cleanup(SetCellExchangeTransportForTest(t, ct))
``

Mcmd/entire/cli/auth/cell_data_api_test.go+3/-9
