ory / kratos

Next-gen identity server replacing your Auth0, Okta, Firebase with hardened security and PassKeys, SMS, OIDC, Social Sign In, MFA, FIDO, TOTP and OTP, WebAuthn, passwordless and much more. Golang, headless, API-first. Available as a worry-free SaaS with the fairest pricing on the market!

Home Page:https://www.ory.sh/kratos/?utm_source=github&utm_medium=banner&utm_campaign=kratos

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ListMySessions API pagination returns duplicate results

aryaniyaps opened this issue · comments

Preflight checklist

Ory Network Project

No response

Describe the bug

I have been trying to use the Ory Kratos Frontend API to list sessions and manage them in my Next.JS frontend application.

I wanted to utilize the newly added token based pagination API, but found out that the frontend listMySessions API returned duplicate results, even when the pageToken value changed.

kratos frontend API client initialization:

import { Configuration, FrontendApi } from "@ory/kratos-client";
import { env } from "./env";

const kratos = new FrontendApi(
  new Configuration({
    basePath: env.NEXT_PUBLIC_KRATOS_PUBLIC_URL,
    baseOptions: { withCredentials: true },
  })
);

Im using react-query for data management on the client side

import { useSuspenseInfiniteQuery } from "@tanstack/react-query";
import parseLinkHeader from "parse-link-header";
import { DEFAULT_PAGE_SIZE } from "../constants";
import kratos from "../kratos";

export default function useSessions() {
  return useSuspenseInfiniteQuery({
    queryKey: ["/sessions"],
    queryFn: async ({ pageParam }) => {
      const { data, headers } = await kratos.listMySessions({
        pageSize: DEFAULT_PAGE_SIZE,
        pageToken: pageParam,
      });

      const linkHeader = headers.link;

      const links = parseLinkHeader(linkHeader);

      return {
        sessions: data,
        nextPageToken: links?.next?.page_token
      };
    },
    initialPageParam: undefined as string | undefined,
    getNextPageParam: (lastPage) => lastPage.nextPageToken,
  });
}

essentially, what is happening is when I call

      const { data, headers } = await kratos.listMySessions({
        pageSize: DEFAULT_PAGE_SIZE,
        pageToken: undefined, // page token defaults to "1" as per the API
      });

and when I'm calling

      const { data, headers } = await kratos.listMySessions({
        pageSize: DEFAULT_PAGE_SIZE,
        pageToken: "XYZ", // assuming that `XYZ` was the next page token
      });

I get the same results i.e. the same list of sessions when using both calls.

Reproducing the bug

  1. Run The ory kratos quickstart using docker compose:
    https://github.com/ory/kratos/blob/master/quickstart-latest.yml
  2. create a number of sessions (say 6) for a particular identity.
  3. fetch the first page of sessions for the identity using the following curl command:
    curl -X GET "http://localhost:4433/sessions?per_page=5"
    
  4. retrieve the link header from the response and get the next page token, XYZ
  5. fetch the next page of sessions for the identity using the following curl command:
    curl -X GET "http://localhost:4433/sessions?per_page=5&page_token=XYZ"
    
  6. We can infer that both the commands return the same set of results

Relevant log output

No response

Relevant configuration

No response

Version

v1.1.0

On which operating system are you observing this issue?

Windows

In which environment are you deploying?

Docker Compose

Additional Context

No response