Skip to content

feat(core): ship isCurrent on account api sessions response#8731

Open
simeng-li wants to merge 1 commit intosimeng-log-13304-p12-add-iscurrent-flag-dev-feature-gated-to-get-apimyfrom
simeng-log-13306-p14-update-api-documentation-for-iscurrent-lands-with-the
Open

feat(core): ship isCurrent on account api sessions response#8731
simeng-li wants to merge 1 commit intosimeng-log-13304-p12-add-iscurrent-flag-dev-feature-gated-to-get-apimyfrom
simeng-log-13306-p14-update-api-documentation-for-iscurrent-lands-with-the

Conversation

@simeng-li
Copy link
Copy Markdown
Contributor

Summary

Stacked on #8729 (P1.2). PR base is the P1.2 branch; rebase to `master` once that lands.

Remove the `EnvSet.values.isDevFeaturesEnabled` guard added in #8729 and ship `isCurrent` on `GET /api/my-account/sessions` to production. Each entry in the response is now unconditionally tagged: `true` for the session whose OIDC uid backs the calling access token, `false` for the others.

What changed

  • `packages/core/src/routes/account/sessions.ts` — drop the dev-feature ternary; the `isCurrent` mapping is unconditional.
  • `packages/core/src/routes/account/index.openapi.json` — extend the `GetSessions` description to document `isCurrent` for SDK / spec consumers.
  • `packages/integration-tests/src/tests/api/account/session.test.ts` — drop the `devFeatureTest.it` wrappers added in #8729. The three `isCurrent` tests now run in every CI configuration.
  • `.changeset/quiet-rivers-tag.md` — patch entry for `@logto/core` and `@logto/schemas` referencing GitHub #8681.

Expected result

  • Production responses include `isCurrent` on every entry. Existing clients that ignore unknown fields are unaffected.
  • Admin user-sessions endpoints (`/users/:userId/sessions`, `/users/:userId/sessions/:sessionId`) are untouched and continue to use `getUserSessionsResponseGuard` without `isCurrent` (cleanly separated in #8729 by the `accountUserExtendedSessionGuard` split).

Reviewer notes

  • Closes LOG-13306. Closes #8681.
  • The original 4-task plan listed P1.4 as docs-only with a separate cleanup PR for the gate. Per agreement, these were collapsed into one PR — see updated LOG-13306 description.

Testing

Integration tests

Checklist

  • `.changeset`
  • unit tests
  • integration tests
  • necessary TSDoc comments

@github-actions github-actions Bot added the feature Cool stuff label Apr 28, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

COMPARE TO master

Total Size Diff 📈 +6.18 KB

Diff by File
Name Diff
.changeset/quiet-rivers-tag.md 📈 +678 Bytes
packages/core/src/middleware/koa-auth/koa-oidc-auth.test.ts 📈 +638 Bytes
packages/core/src/middleware/koa-auth/koa-oidc-auth.ts 📈 +30 Bytes
packages/core/src/middleware/koa-auth/types.ts 📈 +206 Bytes
packages/core/src/routes/account/index.openapi.json 📈 +519 Bytes
packages/core/src/routes/account/sessions.ts 📈 +147 Bytes
packages/integration-tests/src/api/my-account.ts 📈 +14 Bytes
packages/integration-tests/src/helpers/session.ts 📈 +13 Bytes
packages/integration-tests/src/tests/api/account/session.test.ts 📈 +2.94 KB
packages/schemas/src/types/user-sessions.ts 📈 +1.04 KB

Copy link
Copy Markdown
Contributor

@wangsijie wangsijie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 PR Review

This PR removes the dev-feature gate around isCurrent on GET /api/my-account/sessions, documents the field, and makes the related integration tests run in every CI configuration.

  • 🔒 Security: clean
  • 🏗️ Architecture: 0 high, 1 medium
  • 👨‍💻 Engineering: 0 high, 1 medium

Verdict: ⚠️ Needs attention

"operationId": "GetSessions",
"summary": "Get all active sessions",
"description": "Retrieve all non-expired sessions for the user, including session metadata and interaction details when available. A logto-verification-id in header is required for checking sensitive session details.",
"description": "Retrieve all non-expired sessions for the user, including session metadata and interaction details when available. A logto-verification-id in header is required for checking sensitive session details. Each entry includes an `isCurrent` boolean: `true` for the entry whose OIDC session backs the calling access token, `false` for the others. Use this to mark the \"This device\" entry in session-management UIs and to avoid revoking the caller's own session.",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🏗️ Medium: This PR promotes isCurrent to a guaranteed Account API field, but packages/schemas/src/types/user-sessions.ts still models it as optional, so the public @logto/schemas contract remains looser than the shipped API and SDK consumers cannot rely on the new field.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 78b2800. accountUserExtendedSessionGuard now declares isCurrent: z.boolean() (no longer optional). The @logto/schemas exported type matches the runtime contract — every entry in the response carries the field.

"responses": {
"200": {
"description": "Return a list of non-expired sessions of the user."
"description": "Return a list of non-expired sessions of the user. Exactly one entry has `isCurrent: true` per request."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👨‍💻 Medium: The new "exactly one isCurrent: true" guarantee is not true after the caller revokes the session backing its current access token: koaOidcAuth still accepts that token, but findUserActiveSessionsWithExtensions() no longer returns the deleted session, so this response can legitimately contain zero current entries.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Fixed in 78b2800 — softened the OpenAPI prose to at most one isCurrent: true and called out the zero-current case explicitly: when the caller revokes its own session, the access token may remain valid until refresh while the session row is gone, so the response can legitimately have no tagged entry. The schema JSDoc on accountUserExtendedSessionGuard.isCurrent carries the same note.

@simeng-li simeng-li force-pushed the simeng-log-13306-p14-update-api-documentation-for-iscurrent-lands-with-the branch from 8c013d9 to 78b2800 Compare April 29, 2026 07:46
@github-actions github-actions Bot added size/m and removed size/m labels Apr 29, 2026
Remove the `EnvSet.values.isDevFeaturesEnabled` guard added in
LOG-13304. `GET /api/my-account/sessions` now unconditionally tags
the entry whose OIDC session uid backs the calling access token
with `isCurrent: true`. Other entries are `false`.

Also:

- Extend the `GetSessions` OpenAPI description to document
  `isCurrent` semantics for SDK / spec consumers.
- Drop the `devFeatureTest.it` wrappers around the integration
  tests added in LOG-13304; the feature is no longer dev-gated, so
  the tests should run in every CI configuration.
- Add a changeset entry.

Closes LOG-13306. Refs #8681.
@simeng-li simeng-li force-pushed the simeng-log-13304-p12-add-iscurrent-flag-dev-feature-gated-to-get-apimy branch from 84c88ef to 18d4d34 Compare April 29, 2026 07:53
@simeng-li simeng-li force-pushed the simeng-log-13306-p14-update-api-documentation-for-iscurrent-lands-with-the branch from 78b2800 to 0e2e1b2 Compare April 29, 2026 07:54
@github-actions github-actions Bot added size/m and removed size/m labels Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Development

Successfully merging this pull request may close these issues.

2 participants