soundcloud-api-ts-next
    Preparing search index...

    Class CookiePkceStore

    Cookie-based PkceStore implementation.

    Encodes the PKCE verifier into a signed HTTP cookie so it survives across serverless cold starts and multiple server instances without needing an external store (Redis, database, etc.).

    How it works:

    1. On login — call initLogin(), then setCookieHeader(state, ttlMs) to get the Set-Cookie header value. Include this in the login response so the browser stores the signed verifier.
    2. On callback — call getFromRequest(req) to read, verify, and load the verifier from the cookie into the in-process map. Then exchangeCode() will find it via get(state).

    Security: The cookie value is HMAC-SHA256 signed with secret (via Web Crypto SubtleCrypto). Always use a strong random secret (≥ 32 bytes) from an environment variable. The cookie must be set HttpOnly, Secure (in production), and SameSite=Lax.

    Suitable for: Vercel, AWS Lambda, edge runtimes, and any deployment where you cannot share process memory across instances.

    // lib/sc-auth.ts
    import { createSCAuthManager, CookiePkceStore } from "soundcloud-api-ts-next/server";

    export const cookieStore = new CookiePkceStore(process.env.PKCE_SECRET!);
    export const scAuth = createSCAuthManager({
    clientId: process.env.SC_CLIENT_ID!,
    clientSecret: process.env.SC_CLIENT_SECRET!,
    redirectUri: process.env.SC_REDIRECT_URI!,
    pkceStore: cookieStore,
    });

    // app/api/soundcloud/auth/login/route.ts
    import { scAuth, cookieStore } from "@/lib/sc-auth";

    export async function GET() {
    const { url, state } = await scAuth.initLogin();
    const cookieHeader = await cookieStore.setCookieHeader(state, 600_000);
    return new Response(null, {
    status: 302,
    headers: { Location: url, "Set-Cookie": cookieHeader },
    });
    }

    // app/api/soundcloud/auth/callback/route.ts
    import { scAuth, cookieStore } from "@/lib/sc-auth";

    export async function GET(req: Request) {
    await cookieStore.getFromRequest(req); // load verifier from cookie
    const { searchParams } = new URL(req.url);
    const tokens = await scAuth.exchangeCode(
    searchParams.get("code")!,
    searchParams.get("state")!,
    );
    // Store tokens securely and redirect
    }

    Implements

    Index

    Constructors

    • Parameters

      • secret: string

        HMAC-SHA256 signing secret. Use a strong random string from an environment variable (≥ 32 bytes recommended).

      • cookieName: string = "sc_pkce"

        Name of the HTTP cookie. Defaults to "sc_pkce".

      Returns CookiePkceStore

    Properties

    cookieName: string = "sc_pkce"

    Name of the HTTP cookie. Defaults to "sc_pkce".

    Methods

    • Retrieve a verifier by state from the in-process map. Returns undefined if absent or expired.

      Parameters

      • state: string

      Returns string | undefined

    • Read the PKCE cookie from a raw Cookie header string. Useful when working with Node.js IncomingMessage (Pages Router).

      Parameters

      • cookieHeader: string

        The raw Cookie header value from the request.

      Returns Promise<string | undefined>

      // Pages Router handler
      export default async function handler(req, res) {
      await cookieStore.getFromCookieHeader(req.headers.cookie ?? "");
      const tokens = await scAuth.exchangeCode(code, state);
      }
    • Read the PKCE cookie from an incoming request, verify its HMAC signature, and load the state → verifier mapping into the in-process map.

      Call this at the start of your OAuth callback handler so that exchangeCode() can find the verifier via get(state).

      Returns the verifier string if the cookie is valid, undefined otherwise (missing, tampered, or expired cookie).

      Parameters

      • req: Request

        The incoming Request object (Web API / Next.js App Router).

      Returns Promise<string | undefined>

      export async function GET(req: Request) {
      const verifier = await cookieStore.getFromRequest(req);
      if (!verifier) return new Response("Bad request", { status: 400 });
      const tokens = await scAuth.exchangeCode(code, state);
      }
    • Generate the Set-Cookie header value for the PKCE verifier cookie.

      Call this after initLogin() (which calls set() internally) to get the header string to set in your login response. The cookie embeds the state → verifier mapping signed with HMAC-SHA256 so the server can verify integrity on callback.

      Parameters

      • state: string

        The state token returned by initLogin().

      • ttlMs: number

        Cookie lifetime in milliseconds (should match the PKCE TTL).

      • secure: boolean = ...

        Whether to add the Secure cookie flag. Defaults to true when NODE_ENV === "production".

      Returns Promise<string>

      const { url, state } = await scAuth.initLogin();
      const cookieHeader = await cookieStore.setCookieHeader(state, 600_000);
      return new Response(null, {
      status: 302,
      headers: { Location: url, "Set-Cookie": cookieHeader },
      });