Skip to main content

@krakentech/blueprint-auth

40.1.0​

Minor Changes​

  • cfd783c: login: add captchaResponse to the login input (optional)

Patch Changes​

  • 33b7c6e: Fix a type compatibility issue between AuthenticatedGraphQLClient and GraphQLClient that surfaces when consumers use different minor versions of graphql-request within the ^7.2.0 peer dependency range.
  • cacaca1: createAuthMiddleware: grant access to dual anon/dashboard routes when scopedToken cookie is set

40.0.3​

Patch Changes​

  • 1a09d4c: Fix a concurrency issue with the GraphQL client's per-request-level error policies potentially affecting client-level error policies.

    import {
    xErrorPolicyHeader,
    getUserScopedGraphQLClient,
    } from "@krakentech/blueprint-auth";

    const client = getUserScopedGraphQLClient(config, {
    context,
    errorPolicy: "ignore",
    });

    const requestHeaders = { [xErrorPolicyHeader]: "none" };

    const results = await Promise.all([
    // throws error if GraphQL server returns errors
    client.request({ document, variables, requestHeaders }),
    // should ignore errors (client-level error policy)
    client.request({ document: otherDocument, variables: otherVariables }),
    ]);

    When you make concurrent requests using something like above, the error policy of the first request used to also change the error policy of the second request. In this example, the second request could throw an error despite the client-level error policy of ignore.

    Now, the error policies of individual requests are strictly isolated.

40.0.2​

Patch Changes​

  • ea49d51: Bump picomatch to ^4.0.4 for security fixes.

40.0.1​

Please skip 40.0.0 (faulty release) and upgrade directly to 40.0.1 instead.

Major Changes​

  • 0f569c4: Complete overhaul: unified config, unified API, App Router support, and other improvements

    We've added App Router support and introduced a unified config system. You define your authentication setup once and reuse it everywhere. No more copying config across 10+ files.

    Summary​

    • Unified configuration - Create authConfig once, use it in middleware, API handlers, and client code
    • App Router support - Utilities work in all Next.js environments through automatic context detection
    • Less boilerplate - Factory functions accept your config, that's it
    • Better errors - Structured error codes with helpful messages that tell you exactly what went wrong
    • Better types - Centralized config means better inference and validation
    • Better tests - Statement coverage increased from 73% to 99%, achieving 100% function coverage
    • Consistent patterns - Same API conventions across all auth features

    Migration Guide​

    Complete Migration Guide

    See the full migration guide with step-by-step instructions and code examples.

    What's changed​

    Previously, the API wasn't consistent enough for a single unified config object to work with every utility function. This meant you had to pass configuration separately to each function, often repeating the same settings across multiple files. Also, the package only worked with Pages Router.

    Now you create one authConfig object and import it everywhere. Need to update something? Change it in one place, done.

    Separately, we've generalized the low-level utilities to work in all Next.js environments: Pages Router, App Router, Server Actions, you name it. Server functions now accept a flexible context parameter that adapts to your execution environment, replacing the Pages Router-specific req and res parameters.

    We've also added structured error handling with the new AuthError class. Errors now have clear codes that tell you exactly what went wrong and how to fix it.

    We've added comprehensive test coverage for edge cases, error scenarios, and cross-router compatibility.

    The trade-off: this is a breaking change. But the migration is straightforward, and you'll end up with cleaner, more maintainable code. We've migrated all our demo apps to prove it works in practice.

    What you gain:

    • ~200 lines of duplicated config → ~50 lines in one file
    • Change auth setup once instead of hunting through files
    • Type-safe config with build-time validation
    • Future-proof App Router support

    Quick Summary​

    1. Create a centralized authConfig with createAuthConfig
    2. Update middleware to use createAuthMiddleware(authConfig)
    3. Replace API handlers with factory functions (e.g., createLoginHandler(authConfig))
    4. Update client auth to use createClientSideAuth(authConfig, "kraken")
    5. Move custom options to customization and validation nested objects
    6. Update imports: TOKEN_COOKIE_KEYS → AUTH_COOKIE, *Handler → create*Handler
    7. Update cookie references: "access" → "accessToken", "refresh" → "refreshToken", etc.

    Breaking Changes​

    Configuration Changes​

    1. Config gets organized​

    Options are now grouped logically into customization and validation objects. This makes it clearer what each option does and keeps the top level clean.

    Before:

    {
    getCookieOptions: (cookieName) => ({ /* ... */ }),
    setCustomHeaders: (headers) => { /* ... */ },
    shouldValidateUrl: !process.env.IS_TEST,
    }

    After:

    {
    customization: {
    getCookieOptions: (cookieName) => ({ /* ... */ }),
    setCustomHeaders: (headers, authScope) => { /* ... */ },
    },
    validation: {
    validateGraphQLEndpointUrl: !process.env.IS_TEST,
    },
    }

    2. Custom headers get more context​

    The setCustomHeaders callback now receives authScope for user vs organization requests. This unifies the API across the package: write your header logic once and reuse it everywhere.

    Before:

    setCustomHeaders: (headers: Headers) => void

    After:

    customization: {
    setCustomHeaders: (headers: Headers, authScope: "user" | "organization") => void | Promise<void>
    }

    getCookieOptions now expects SerializeOptions | undefined. Return undefined to use defaults for specific cookies. Customize only what you need.

    Before:

    getCookieOptions: (cookieName: CookieName) =>
    Omit<HttpContext, "req" | "res">;

    After:

    customization: {
    getCookieOptions: (cookieName: CookieName) => SerializeOptions | undefined;
    }

    4. Route config gets consistent names​

    Route parameter extractors now use consistent naming and accept an options object for easier extensibility.

    Before:

    appRoutes: {
    anon: {
    getPreSignedKey: (url) => ({ preSignedKey }),
    },
    masquerade: {
    getUserIdAndMasqueradeToken: (url) => ({ userId, masqueradeToken }),
    },
    }

    After:

    appRoutes: {
    anon: {
    getAnonParams({ url }) {
    return { preSignedKey };
    },
    },
    masquerade: {
    getMasqueradeParams({ url }) {
    return { userId, masqueradeToken };
    },
    },
    }

    Server-Side Changes​

    5. Server functions now use context parameter​

    Server-side functions now accept a generic context parameter instead of explicit req and res. This enables automatic environment detection and App Router support.

    Before:

    // Old API - Pages Router specific
    const { userScopedClient, organizationScopedClient } =
    await getServerSideGraphQLClients({
    krakenConfig: {
    /* ... */
    },
    req,
    res,
    });

    After:

    // Pages Router (getServerSideProps, API routes)
    const client = await getUserScopedGraphQLClient(authConfig, { req, res });

    // App Router (server components)
    import { cookies, headers } from "next/headers";
    const client = await getUserScopedGraphQLClient(authConfig, {
    cookies,
    headers,
    });

    // App Router (route handlers)
    export async function GET(req: NextRequest) {
    const client = await getUserScopedGraphQLClient(authConfig, { req });
    }

    The context object type adapts automatically based on your execution environment.

    6. Middleware gets factory pattern​

    Middleware now uses a factory for consistency with API handlers and compatible with the unified config.

    Before:

    import { authMiddleware } from "@krakentech/blueprint-auth/middleware";
    import type { NextRequest, NextResponse } from "next/server";

    export async function middleware(req: NextRequest) {
    const res = NextResponse.next();
    return await authMiddleware({
    appRoutes: {
    /* ... */
    },
    krakenConfig: {
    /* ... */
    },
    req,
    res,
    // ... more config
    });
    }

    After:

    import { createAuthMiddleware } from "@krakentech/blueprint-auth/middleware";
    import { authConfig } from "@/lib/auth/config";

    export const middleware = createAuthMiddleware(authConfig);

    export const config = {
    matcher: ["/dashboard/:path*", "/login"],
    };

    7. Redirect callbacks support fallback​

    customSuccessResponse and customErrorResponse now expect NextResponse | undefined. Return undefined to use default behavior. Perfect for handling specific cases while delegating others.

    Before:

    customSuccessResponse: ({ url }) => NextResponse.redirect(url);

    After:

    customSuccessResponse({ url }) {
    if (someCondition) {
    return NextResponse.redirect(url);
    }
    // uses default success response
    }

    8. API handlers now use factories​

    Handlers are now factories that work with the unified config. You can export them directly from your API routes, reducing boilerplate code.

    Before:

    import { loginHandler } from "@krakentech/blueprint-auth/server";
    import type { NextApiRequest, NextApiResponse } from "next";

    export default async function handler(
    req: NextApiRequest,
    res: NextApiResponse
    ) {
    await loginHandler({
    krakenConfig: {
    /* ... */
    },
    req,
    res,
    edgeConfig: {
    /* ... */
    },
    encryption: {
    /* ... */
    },
    });
    }

    After:

    import { createLoginHandler } from "@krakentech/blueprint-auth/server";
    import { authConfig } from "@/lib/auth/config";

    export default createLoginHandler(authConfig);

    Same pattern for all handlers: loginHandler → createLoginHandler, logoutHandler → createLogoutHandler, etc.

    9. GraphQL client functions split for clarity​

    getServerSideGraphQLClients is replaced by two separate functions: getUserScopedGraphQLClient and getOrganizationScopedGraphQLClient. Import only what you need.

    Before:

    import { getServerSideGraphQLClients } from "@krakentech/blueprint-auth/server";

    const { userScopedClient, organizationScopedClient } =
    await getServerSideGraphQLClients({
    krakenConfig: {
    /* ... */
    },
    req,
    res,
    });

    After:

    import {
    getUserScopedGraphQLClient,
    getOrganizationScopedGraphQLClient,
    } from "@krakentech/blueprint-auth/server";
    import { authConfig } from "@/lib/auth/config";

    const userClient = await getUserScopedGraphQLClient(authConfig, { req, res });
    const orgClient = await getOrganizationScopedGraphQLClient(authConfig, {
    req,
    res,
    });

    Client-Side Changes​

    10. Client auth uses unified config​

    To support both routing paradigms, client auth needs to know which one you're using. Add router to your config and pass it through. The defaultTarget parameter has moved to the second argument of the function.

    Before:

    import { createClientSideAuth } from "@krakentech/blueprint-auth/client";

    export const {
    AuthProvider,
    useAuth,
    useLogin,
    // ...
    } = createClientSideAuth({
    apiRoutes: {
    graphql: { kraken: "/api/graphql" },
    login: "/api/auth/login",
    // ...
    },
    defaultTarget: "kraken",
    });

    After:

    import { createClientSideAuth } from "@krakentech/blueprint-auth/client";
    import { authConfig } from "@/lib/auth/config";

    export const {
    AuthProvider,
    useAuth,
    useLogin,
    // ...
    } = createClientSideAuth(
    authConfig, // includes router: "pages-router" or "app-router"
    "kraken" // defaultTarget is now the second argument
    );

    11. AuthProvider props changed​

    AuthProvider no longer takes appRoutes as a prop (now in authConfig). Handler signatures have changed to receive a defaultRedirect callback function.

    Before:

    <AuthProvider
    appRoutes={{
    dashboard: "/dashboard",
    login: "/login",
    }}
    handlers={{
    onLoginSuccess() { /* ... */ },
    onLoginError({ errors }) { /* ... */ },
    onLogout() { /* ... */ },
    }}
    >

    After:

    <AuthProvider
    handlers={{
    onLoginSuccess(defaultRedirect) { /* ... */ },
    onLoginError(errorCode, defaultRedirect) { /* ... */ },
    onLogoutSuccess(defaultRedirect) { /* ... */ },
    onLogoutError(errorCode, defaultRedirect) { /* ... */ },
    }}
    >

    12. Handler signatures receive defaultRedirect callback​

    All AuthProvider handlers now receive a defaultRedirect callback function. The onLoginError handler receives an ErrorCode string instead of a KrakenError[] array. The onLogout handler splits into separate onLogoutSuccess and onLogoutError handlers.

    Before:

    handlers: {
    onLoginSuccess(): void,
    onLoginError({ errors }: { errors: KrakenError[] }): void,
    onLogout(): void,
    }

    After:

    handlers: {
    onLoginSuccess(defaultRedirect: () => void): void | Promise<void>,
    onLoginError(errorCode: ErrorCode, defaultRedirect: () => void): void | Promise<void>,
    onLogoutSuccess(defaultRedirect: () => void): void | Promise<void>,
    onLogoutError(errorCode: ErrorCode, defaultRedirect: () => void): void | Promise<void>,
    }

    13. useLogin accepts nextPage option​

    The shouldRedirectToNextPage boolean flag is replaced by nextPage. Set it to null to prevent redirect, or provide a path to redirect to a specific page.

    Before:

    const login = useLogin({
    shouldRedirectToNextPage: false,
    });

    After:

    const login = useLogin({
    nextPage: null,
    });

    14. useLogout accepts options​

    The hook now accepts an options object. Use nextPage to control the redirect destination, or set it to null to prevent redirect.

    Before:

    const logout = useLogout();

    After:

    const logout = useLogout({
    nextPage: "/goodbye",
    });

    15. useKrakenAuthErrorHandler uses options object​

    The hook now takes an options object instead of a single function. The onError callback receives a defaultRedirect function as its second parameter. The getAuthErrorCode function is no longer returned from the hook; import getErrorCode directly from the main package instead.

    Before:

    const { getAuthErrorCode, handleKrakenErrors } = useKrakenAuthErrorHandler(
    (error) => {
    // custom error handling
    }
    );
    const errorCode = getAuthErrorCode(error);

    After:

    import { getErrorCode } from "@krakentech/blueprint-auth/utils";

    const { handleKrakenErrors } = useKrakenAuthErrorHandler({
    onError: (error, defaultRedirect) => {
    // custom error handling
    },
    redirectType: "replace",
    });
    const errorCode = getErrorCode(error);

    16. useSession refetch behavior changed​

    The useSession hook no longer automatically refetches when the window regains focus or network reconnects. This prevents UI tearing when sessions expire while users are viewing protected pages.

    Previous behavior: Refetch on window focus/reconnect could cause authenticated UI to disappear mid-session.

    New behavior: Session state remains stable during page view. Users redirect to login on next navigation or GraphQL request (when using useKrakenAuthErrorHandler).

    Import & Export Changes​

    The old TOKEN_COOKIE_KEYS used short aliases (access, refresh) that didn't match actual cookie names. This was confusing when debugging. AUTH_COOKIE uses real names.

    Before:

    import { TOKEN_COOKIE_KEYS } from "@krakentech/blueprint-auth";

    TOKEN_COOKIE_KEYS.access; // actually "accessToken"
    TOKEN_COOKIE_KEYS.refresh; // actually "refreshToken"

    After:

    import { AUTH_COOKIE } from "@krakentech/blueprint-auth";

    AUTH_COOKIE.accessToken; // "accessToken"
    AUTH_COOKIE.refreshToken; // "refreshToken"

    18. Import and export names updated​

    The API has been redesigned for consistency. Handlers use the create* factory pattern, and utilities have clearer names.

    Key changes:

    • Utilities: createKrakenOAuthURI → generateKrakenOAuthURI, getSessionData → getSession
    • Constants: TOKEN_COOKIE_KEYS → AUTH_COOKIE (covered in #17)

    New error handling exports:

    • AuthError, BlueprintAuthErrorCode, getErrorCode, isBlueprintAuthErrorCode

    See the migration guide for a complete list of renamed exports.

    19. getErrorCode now standalone export​

    The getErrorCode function is no longer returned from useKrakenAuthErrorHandler. Import it directly from the main package.

    Before:

    const { getAuthErrorCode } = useKrakenAuthErrorHandler(/* ... */);
    const errorCode = getAuthErrorCode(error);

    After:

    import { getErrorCode } from "@krakentech/blueprint-auth/utils";
    const errorCode = getErrorCode(error);

    20. New Session State​

    The getSession server function and useSession client hook now return the authMethod field as a replacement for auth method flags, i.e. isMasquerading, isMobileWebView, and isScopedSession:

    • authMethod: Identifies the active authentication method, i.e. "email", "oauth", "scoped", "masquerade", "mobile-web-view", or null.

    Example usage:

    const session = await getSession({ context });

    if (session.isAuthenticated) {
    return <LogoutButton />;
    } else {
    return <LoginButton />;
    }

    if (session.authMethod === "masquerade") {
    return <MasqueradeBanner />;
    }

    if (session.authMethod === "scoped") {
    return <PaymentDetailsCard />;
    } else {
    return <PaymentDetailsForm />;
    }

    if (session.authMethod === "mobile-web-view") {
    return <UpdateAppLink />;
    } else {
    return <DownloadAppLink />;
    }

    See the @krakentech/blueprint-api changelog for the SessionState type changes.

    Middleware Behavior​

    21. Scoped token priority handling changed​

    The auth middleware now correctly enforces authentication priority. This is a breaking behavior change that may affect applications where users click anonymous session links while already authenticated.

    Previous behavior: When a user with an existing authenticated session (e.g., accessToken) navigated to an anonymous session URL (e.g., /anon/{preSignedKey}), the middleware would replace their authenticated session with the scoped token, effectively downgrading their access.

    New behavior: The middleware now respects authentication priority. If a user already has a higher-priority authentication method (access token, masquerade token, or mobile web view token), the scoped token will not override it. The user maintains their existing authenticated session.

    Priority order (highest to lowest):

    1. masquerade - Staff impersonation
    2. mobile-web-view - Mobile app integration
    3. oauth or email - Full authenticated sessions
    4. scoped - Anonymous/pre-signed key access

    Impact: If your application relied on anonymous session links replacing authenticated sessions, you'll need to update your logic.

    Environment​

    22. New required environment variable​

    krakenConfig.xClientIpSecretKey is now required. Set the KRAKEN_X_CLIENT_IP_SECRET_KEY environment variable to provide this value.

    New Features​

    New Utility: getActiveAuthMethod​

    A new utility function is available via createAuthCookieUtils and createAppRouterAuth that determines which authentication method is currently active based on cookie priority:

    const { getActiveAuthMethod } = createAuthCookieUtils({ context });
    const cookies = await getAuthCookies();
    const authMethod = getActiveAuthMethod(cookies);

    Priority order (highest to lowest):

    1. masquerade - Staff impersonation
    2. mobile-web-view - Mobile app integration
    3. oauth or email - Full authenticated sessions
    4. scoped - Anonymous/pre-signed key access

    This utility is particularly useful when you need to determine the active auth method without loading the full session state.

  • 0f569c4: Add error policy support to both getUserScopedGraphQLClient, getOrganizationScopedGraphQLClient server functions + useGraphQLClient hook. This allows callers to specify how GraphQL errors should be handled in responses. This change allows you to pass in client-level and per-request-level error policies.

    import {
    xErrorPolicyHeader,
    getUserScopedGraphQLClient,
    } from "@krakentech/blueprint-auth";

    const client = getUserScopedGraphQLClient(config, {
    context,
    errorPolicy: "ignore", // or "all" or "none" (default)
    });

    const response = await client.request({
    document,
    variables,
    requestHeaders: {
    [xErrorPolicyHeader]: "ignore", // or "all" or "none" (default)
    },
    });

    Same for getOrganizationScopedGraphQLClient. The errorPolicy option at the client level will apply to all requests made using that client instance, unless overridden by a per-request error policy.

    Also supported by the useGraphQLClient hook in the frontend, where you can pass the error policy in the requestHeaders when making a request with the client obtained from the hook.

    const { graphQLClient } = useGraphQLClient({
    errorPolicy: "all", // Client-level error policy
    });

    const response = await graphQLClient.request({
    document,
    variables,
    requestHeaders: {
    [xErrorPolicyHeader]: "ignore", // Per-request override
    },
    });

    useGraphQLClient now accepts an object as prop instead of just target (string), to allow passing additional options like errorPolicy.

    If no error policy is provided, the default behavior is "none", which means GraphQL errors will be treated as errors and will cause the request to throw.

    The reason why we're using the requestHeaders to pass the per-request error policy is to avoid breaking changes to the existing function signature so that it matches the existing request function from graphql-request. This way, you can still use them interchangeably without needing to refactor existing code that uses graphql-request directly.

    Note: since graphQLHandler uses the userScopedGraphQLClient under the hood, you can also pass the xErrorPolicyHeader in the requestHeaders when making requests through graphQLHandler to control error handling on a per-request basis which is what useGraphQLClient is designed to point to.

    BREAKING CHANGE: The useGraphQLClient hook now accepts an object as prop instead of just target (string), to allow passing additional options like errorPolicy.

    - useGraphQLClient(target: string)
    + useGraphQLClient({ target: string, errorPolicy: ErrorPolicy })

Patch Changes​

  • Updated dependencies [0f569c4]
    • @krakentech/blueprint-api@4.0.0

39.5.0​

Minor Changes​

  • 27be09b: getServerSideGraphQLClients.organizationScopedGraphQLClient no longer tries to update the organization token in the edge config if the token coming back from cache is invalid/expired. We solely rely on the updateOrgTokenHandler cron job to update the token in the edge config.

    This change is mainly meant to drastically reduce the number of requests to Vercel's Edge Config API and reduce the risk of hitting the rate limit.

39.4.0​

Minor Changes​

  • ce72e28: Allow to specify a custom predicate to determine if the GraphQL client's access token has expired and should be renewed.

39.3.3​

Patch Changes​

  • 9cbaf01: Add the new GraphQL DOS protection checks/tests so the handler and API routes explicitly validate payload size and source IP patterns before processing.

39.3.2​

Patch Changes​

  • 03b6dc4: Security Update: Next.js 15.5.10

    This release includes a critical dependency update for Next.js to address two medium-severity security vulnerabilities discovered in self-hosted configurations:

    • CVE-2025-59471: Fixes a Denial of Service (DoS) vulnerability in the Image Optimizer where large remote images could cause memory exhaustion.
    • CVE-2025-59472: Addresses a vulnerability in Partial Pre-Rendering (PPR) that could allow unauthenticated requests to trigger out-of-memory conditions.

    Type: Security Patch. Action Required: None (Internal dependency bump)

39.3.1​

Patch Changes​

  • 46822c3: authMiddleware: fix issue where the refreshToken value wasn't being properly asserted on the login path if statement.

39.3.0​

Minor Changes​

  • 54ffe17: Add logging system that allows consumers to choose log levels via environment variables. BP_AUTH_LOG_LEVEL can be set to NONE, ERROR, WARN, INFO and DEBUG to control the verbosity of the logs emitted by the package. By default, the log level is set to INFO (which means that INFO, WARN and ERROR messages will be logged since they are of higher severity).

39.2.2​

Patch Changes​

39.2.1​

Patch Changes​

  • c971384: fix(security): upgrade Next.js from 15.4.5 to 15.5.7

    Updated Next.js dependency to address security vulnerabilities. This is a devDependency upgrade that ensures the packages are built and tested with the latest secure version of Next.js.

39.2.0​

Minor Changes​

  • db12b8c: authMiddleware + getServerSideGraphQLClients: added support for refreshing the MWAuthToken (mobile webview) when invalid/expired, using the MWRefreshToken cookie.

39.1.2​

Patch Changes​

  • 2567a7c: New bundling strategy for better performance

    • Unbundle mode Packages are now bundled using tsdown's unbundle mode. This mode drastically reduces the number of generated file compared to the glob-filtered entries we used before, and prevented proper tree-shaking.

    • Automatic package.json exports tsdown is now responsible for generating the package.json exports, main, module, and types fields. This ensures packages follow best practices.

39.1.1​

Patch Changes​

  • b783f71: loginHandler and graphqlHandler: remove noisy Unexpected error response. This could mean that the isKrakenErrorResponse type guard is not working as expected. log message.

39.1.0​

Minor Changes​

  • 535870e: Rename SessionData to SessionState and add isScopedSession "flag".

    - import type { SessionData } from "@krakentech/blueprint-auth";
    + import type { SessionState } from "@krakentech/blueprint-api";

    This type is now coming from @krakentech/blueprint-api and re-exported by @krakentech/blueprint-auth for convenience. The goal being: having a single source of truth.

    Because of this change, the new SessionState type now includes the isScopedSession boolean flag:

    type SessionState = {
    isAuthenticated: boolean;
    isMasquerading: boolean;
    isMobileWebView: boolean;
    + isScopedSession: boolean;
    sub: string | null;
    };

    These changes affect any session-related code: useSession hook, sessionHandler, etc.

39.0.1​

Patch Changes​

  • c045425: Fix peer dependencies to use ^ instead of exact versions.

    -    "@krakentech/blueprint-api": "3.3.0",
    + "@krakentech/blueprint-api": "^3.3.0",

    - "@vercel/edge-config": "1.1.0",
    + "@vercel/edge-config": "^1.1.0",

39.0.0​

Major Changes​

  • 40dcf89: Replace useSecureCookie with getCookieOptions prop. This allows more flexibility in cookie configuration, such as setting different options based on the environment or specific requirements. It also allows different options for different cookies if needed.

    Cookies also now default to sameSite: 'lax' to allow for a better out-of-the-box experience, while still being secure. This allows for easier integration with third-party services that may require cookies to be sent in cross-site requests, such as OAuth providers or redirect from other domains (e.g. email links).

    It stills ships with sensible defaults:

    {
    expires, // same as before, depends on the cookie being set but it's based on the token expiry (if available)
    httpOnly: true,
    secure: true,
    sameSite: "lax"
    }

    What you need to change is:

    {
    - useSecureCookie: false;
    + getCookieOptions: () => ({ secure: false }),
    }

    You can now also provide different options based on the cookie name:

    {
    getCookieOptions: (cookieName) => {
    if (cookieName === "masquerade") {
    return { secure: true, sameSite: "strict" };
    }
    return { secure: false, sameSite: "lax" };
    },
    }

38.0.3​

Patch Changes​

  • 34f0b6d: authMiddleware: support scopedToken being used as an actual access token, allowing access to any anon routes when present. A good example would be magic link login flows.

    Example usage:

    await authMiddleware({
    appRoutes: {
    anon: {
    getPreSignedKey: (url) => {
    if (url.pathname.startsWith("/anon")) {
    const [_anon, preSignedKey] = url.pathname.split("/").filter(Boolean);

    return { preSignedKey };
    }

    if (url.pathname.startsWith("/dashboard")) {
    return { preSignedKey: url.searchParams.get("preSignedKey") };
    }
    },
    pathname: ["/anon", "/dashboard"],
    },
    },
    ...
    });

38.0.2​

Patch Changes​

  • be3f2bd: useLogout: invalidate (instead of resetting) the useSession query cache since resetting it sets data to undefined and we don't want that since that can make deconstruction fail (for example const { data: { isAuthenticated } } = useSession()).

38.0.1​

Patch Changes​

  • dfaaa0b: Masquerading: improve error handling so that it's easier to understand why it fails

38.0.0​

Patch Changes​

  • e2346c1: useGraphQLClient.userScopedGraphQLClient: automatically prepend the window.location.origin when a relative path is provided as the apiRoutes.graphql to the createClientSideAuth function.
  • Updated dependencies [7dc77b4]
    • @krakentech/blueprint-api@3.3.0

37.0.0​

Major Changes​

  • 96c4eb3: The cookies-next dependency was updated to v6.1.0 as a first step toward App Router support.

    Key changes

    • Server-side utility functions from cookies-next are now asynchronous.

    Migration guide

    • @krakentech/blueprint-auth

    The getSessionData function is now asynchronous.

    - const session = getSessionData()
    + const session = await getSessionData()

    The sessionHandler API route handler is now asynchronous.

    The getAuthCookies, getRefreshToken, getSecureCookie, removeAllCookies, removeAuthCookies, removeSecureCookies, and setSecureCookie utility functions returned from createAuthCookieUtils are now asynchronous.

      const {
    getAuthCookies
    getRefreshToken
    getSecureCookie
    removeAllCookies
    removeAuthCookies
    removeSecureCookies
    setSecureCookie
    } = createAuthCookieUtils({ req, res })

    - const cookies = getAuthCookies()
    + const cookies = await getAuthCookies()

    - const accessToken = getSecureCookie("access")
    + const accessToken = await getSecureCookie("access")

    - removeAllCookies()
    + await removeAllCookies()

    - removeAuthCookies()
    + await removeAuthCookies()

    - removeSecureCookies()
    + await removeSecureCookies(["access", "refresh"])

    - setSecureCookie({ key: "access", value: "foo" })
    + await setSecureCookie({ key: "access", value: "foo" })
    • @krakentech/blueprint-onboarding

    The deleteCookieOnServer utility function returned by createNextWizard is now asynchronous.

    - deleteCookieOnServer()
    + await deleteCookieOnServer()

Minor Changes​

  • 63447ac: Allow Next 15 and React 19 as peer dependencies.

    The minimum required versions are still the same:

    • next@14.2.25
    • react@18.2.0
    • react-dom@18.2.0.
    • @types/react@18.3.23

36.0.1​

Patch Changes​

  • Updated dependencies [e4dc37d]
    • @krakentech/blueprint-api@3.2.1

36.0.0​

Patch Changes​

  • Updated dependencies [72176a1]
  • Updated dependencies [12e020f]
    • @krakentech/blueprint-api@3.2.0

35.0.0​

Patch Changes​

  • Updated dependencies [8982f0f]
    • @krakentech/blueprint-api@3.1.0

34.0.1​

Patch Changes​

  • Updated dependencies [bf089bc]
    • @krakentech/blueprint-api@3.0.1

34.0.0​

Major Changes​

  • bad97b4: Bump graphql-request from ^6.1.0 to ^7.2.0

Patch Changes​

  • Updated dependencies [bad97b4]
    • @krakentech/blueprint-api@3.0.0

33.1.0​

Minor Changes​

  • e4e85cb: loginHandler: strip out anything from the response that could help bad actors exploit Kraken's systems by using its response to determine if a user exists or not, if the user is locked out, if the password is correct, etc.

    Before​

    {
    "data": {
    "obtainKrakenToken": null
    },
    "errors": [
    {
    "message": "Invalid data.",
    "locations": [
    {
    "line": 3,
    "column": 9
    }
    ],
    "path": ["obtainKrakenToken"],
    "extensions": {
    "errorType": "VALIDATION",
    "errorCode": "KT-CT-1138",
    "errorDescription": "Please make sure the credentials are correct.",
    "errorClass": "VALIDATION",
    "validationErrors": [
    {
    "message": "Please make sure the credentials are correct.",
    "inputPath": ["input", "email"]
    },
    {
    "message": "Please make sure the credentials are correct.",
    "inputPath": ["input", "password"]
    }
    ]
    }
    }
    ]
    }

    After​

    {
    "data": null,
    "errors": [
    {
    "message": "Invalid data.",
    "extensions": {
    "errorCode": "KT-CT-1138"
    }
    }
    ]
    }

33.0.0​

Patch Changes​

  • Updated dependencies [6ed7c25]
    • @krakentech/blueprint-api@2.0.0

32.1.0​

Minor Changes​

  • 661841b: authMiddleware: ensure that all auth-related cookies are cleared if the user is not authenticated in any way.
  • e3e3cd8: getServerSideGraphQLClients: stop attempting to refresh tokens for masquerade/scopes sessions since they have no refresh token.
  • e3e3cd8: authMiddleware: add masqueradeExpires prop so that consumers can customize the expiration time of masquerade cookies. By default, it is set to 1 hour.
  • e3e3cd8: Set expiry times for all auth-related cookies to prevent issues with cookie expiration.

32.0.0​

Major Changes​

  • 515ef52: Remove withBlueprintAuth since, as of blueprint-api@1.0.0, you no longer have to use it in your next.config file. This util was previously masking an issue where @tanstack/react-query was being imported in server-side code and, since blueprint-api client code has been split into its own submodule, it is no longer necessary. (middleware is importing from the api package, that's why we needed this workaround before)

Minor Changes​

  • 7bf9be6: Specify external relative imports file extensions: from 'next/compat/router to from 'next/compat/router.js' to ensure compatibility with ESM imports.

31.1.1​

Patch Changes​

  • 8f195fc: Set files: ["dist"]
  • Updated dependencies [8f195fc]
    • @krakentech/blueprint-api@1.2.1

31.1.0​

Minor Changes​

  • 3e02b23: Rename the X-Client-IP and X-Client-IP-Authorization headers to X-Kraken-Client-IP and X-Kraken-Client-IP-Authorization. Because the X-Client-IP header has been deprecated and will be removed on 2025-08-01.

31.0.0​

Patch Changes​

  • Updated dependencies [0401bcc]
    • @krakentech/blueprint-api@1.2.0

30.0.0​

Patch Changes​

  • Updated dependencies [9926ab8]
    • @krakentech/blueprint-api@1.1.0

29.0.0​

Patch Changes​

  • Updated dependencies [507d46c]
    • @krakentech/blueprint-api@1.0.0

28.1.0​

Minor Changes​

  • fdd22ba: getServerSideGraphQLClients: fix issue where requests made using the organizationScopedGraphQLClient (when the cached organization token is invalid) would not try to get the latest organization token from the Edge Config directly from Vercel through a "GET" request and instead get a new token from Kraken and (try to) update the Edge Config with it, which would result in us making so many requests that we would hit Vercel's Edge Config API rate limit.

28.0.0​

Patch Changes​

  • Updated dependencies [639224c]
    • @krakentech/blueprint-api@0.8.0

27.0.0​

Minor Changes​

  • 6343863: Turn the package into an ES Module. This includes:

    • Adding "type": "module" to the package.json
    • Updating the exports field to include both ESM and CommonJS versions
    • Ensuring all imports and exports are compatible with ESM

    It shouldn't break any existing functionality, as the CommonJS version is still available for compatibility.

Patch Changes​

  • Updated dependencies [6343863]
    • @krakentech/blueprint-api@0.7.0

26.2.0​

Minor Changes​

  • fd482bf: logoutHandler/useLogout: change the method to POST from GET since using POST is a security best practice to prevent Cross-Site Request Forgery (CSRF) when it comes to state-changing requests.

    You might have to update any mocking you're doing when it comes to logging out since it now expects a POST request instead of GET.

Patch Changes​

  • fd482bf: loginHandler: validate the req.body before making the request to Kraken

26.1.1​

Patch Changes​

  • 971dd01: # Enable tree-shaking of blueprint packages

    The blueprint packages are now code-split and tagged as side-effect free. Bundlers such as Webpack are able to perform tree-shaking and only include necessary code in application bundles.

  • Updated dependencies [971dd01]

    • @krakentech/blueprint-api@0.6.1

26.1.0​

Minor Changes​

  • 255b22d: getServerSideGraphQLClients: remove x-raw-cookies since we don't need them anymore + they make some requests to Kraken return a 400 - Request Header Or Cookie Too Large error

26.0.0​

Major Changes​

  • 6394ea7: The graphqlHandler does not handle organization-scoped requests anymore, all organization-scoped requests need to be performed server-side using the organizationScopedGraphQLClient returned by getServerSideGraphQLClients.

    The edgeConfig, encryption, krakenConfig.organizationSecretKey, and allowedOrganizationScopedOperations are now unnecessary.

      graphqlHandler({
    req,
    res,
    krakenConfig: {
    graphqlEndpoint,
    - organizationSecretKey: process.env.KRAKEN_ORGANIZATION_KEY,
    xClientIpSecretKey: process.env.KRAKEN_X_CLIENT_IP_SECRET_KEY,
    },
    - encryption: {
    - key: process.env.AUTH_ENCRYPTION_KEY,
    - iv: process.env.AUTH_ENCRYPTION_IV,
    - },
    - edgeConfig: {
    - envVar: process.env.EDGE_CONFIG,
    - teamId: process.env.VERCEL_TEAM_ID,
    - authToken: process.env.VERCEL_AUTH_TOKEN,
    - },
    - allowedOrganizationScopedOperations: ['thirdPartyViewer'],
    });

    The useGraphQLClients hook has been renamed useGraphQLClient as it now only return the userScopedGraphQLClient:

    - import { useGraphQLClients } from '@krakentech/blueprint-auth'
    + import { useGraphQLClient } from '@krakentech/blueprint-auth'
    - const { userScopedGraphQLClient } = useGraphQLClients()
    + const { userScopedGraphQLClient } = useGraphQLClient()

    Client-side requests made using the organizationScopedGraphQLClient should be moved server-side. In most cases the request can be done during the server-side rendering of the page, i.e. in getServerSideProps. If the request was performed in response to a user interaction, the request should be performed by a custom API route handler.

  • 3c4aa75: Client-side hooks and the AuthProvider should now be constructed using the createClientSideAuth builder function.

    Somewhere in your project, export the functions returned by createClientSideAuth, e.g. in src/lib/bluerprint-auth/client.ts.

    import { createClientSideAuth } from "@krakentech/blueprint-auth/client";

    export const {
    AuthProvider,
    useAuth,
    useGraphQLClient,
    useLogin,
    useLogout,
    useSession,
    useKrakenAuthErrorHandler,
    } = createClientSideAuth({
    apiRoutes: {
    graphql: {
    kraken: "/api/graphql/kraken",
    },
    login: "/api/auth/login",
    logout: "/api/auth/logout",
    session: "/api/auth/session",
    },
    defaultTarget: "kraken",
    });

    In application code, replace imports from @krakentech/blueprint-auth/client by the create functions.

    - import { AuthProvider } from "@krakentech/blueprint-auth/client"
    + import { AuthProvider } from "@/lib/blueprint-auth/client"

    If your application needs to target multiple GraphQL APIs using graphqlHandler, you should create one GraphQL API route per back-end, and provide the API routes to createClientSideAuth. You can define the default back-end to target to run client-side queries.

    export const { ... } = createClientSideAuth({
    apiRoutes: {
    graphql: {
    kraken: "/api/graphql/kraken",
    oe: "/api/graphql/oe",
    },
    ...
    },
    defaultTarget: "kraken",
    })

    In order to perform a client-side request against the back-end of your choice, the useGraphQLClient hook takes an optional target argument.

    import { useGraphQLClient } from "@/lib/blueprint-auth/client";

    // make requests to `apiRoutes.graphql.kraken (defaultTarget)`
    const { userScopedGraphQLClient } = useGraphQLClient();
    const { userScopedGraphQLClient } = useGraphQLClient("kraken");

    // make requests to `apiRoutes.graphql.oe`
    const { userScopedGraphQLClient } = useGraphQLClient("oe");
  • ef0274f: Homogenization of the APIs throughout the package utility functions and API handlers:

    1. krakenGraphqlApiUrl → krakenConfig.graphqlEndpoint

      The krakenGraphqlApiUrl option of getServerSideGraphQLClients has been moved to krakenConfig.graphqlEndpoint for consistency.

      const { userScopedGraphQLClient } = getServerSideGraphQLClients({
    context,
    - krakenGraphqlApiUrl: process.env.KRAKEN_AUTH_ENDPOINT,
    + krakenConfig: {
    + graphqlEndpoint: process.env.KRAKEN_AUTH_ENDPOINT,
    + },
    })
    1. appRoutes and apiRoutes now require object format

      All variants of the appRoutes, and apiRoutes configuration options are now derived from the same AppRoutes, and ApiRoutes types respectively. Use { pathname: string } instead of plain strings.

    The appRoutes configuration option of the AuthProvider follows the new AppRoutes interface.

      <AuthProvider
    appRoutes={{
    - dashboard: '/dashboard',
    + dashboard: {
    + pathname: '/dashboard',
    + },
    - login: '/login',
    + login: {
    + pathname: '/login',
    + },
    }}
    >

    The appRoutes configuration option of the authMiddleware follows the new AppRoutes interface.

      authMiddleware({
    appRoutes: {
    anon: {
    - path: '/anon',
    + pathname: '/anon',
    getPreSignedKey(url) {...},
    },
    dashboard: {
    - path: '/dashboard',
    + pathname: '/dashboard',
    },
    login: {
    - path: '/login',
    + pathname: '/login',
    },
    masquerade: {
    - path: '/masquerade',
    + pathname: '/masquerade',
    getUserIdAndMarqueradeToken(url) {...},
    },
    }
    })
    1. krakenOAuthApiRoute moved into apiRoutes.krakenOAuth

    The krakenOAuthApiRoute configuration option of createKrakenOAuthURI has been moved to apiRoutes.krakenOAuth for consistency.

      createKrakenOAuthURI({
    req,
    res,
    - krakenOAuthApiRoute: '/api/auth/kraken-oauth',
    + apiRoutes: {
    + krakenOAuth: '/api/auth/kraken-oauth'
    + },
    })

    The appRoutes configuration option of krakenOAuthHandler follows the new AppRoutes interface, additionally appRoutes.krakenOAuth has been moved to apiRoutes.krakenOAuth for consistency.

      krakenOAuthHandler({
    req,
    res,
    appRoutes: {
    - dashboard: '/dashboard',
    + dashboard: {
    + pathname: '/dashboard',
    + },
    - login: '/login',
    + login: {
    + pathname: '/login',
    + },
    - krakenOAuth: '/api/auth/kraken-oauth'
    },
    + apiRoutes: {
    + krakenOAuth: '/api/auth/kraken-oauth'
    + },
    })
    1. Defaults from environment variables

      Default values for the krakenConfig configuration option are derived from environment variables consistently throughout the utility functions and handlers of the package. This means, unless a value differing from the environment variable needs to be used, the krakenConfig configuration option can be omitted completely or partially in:

      • authMiddleware
      • createKrakenOAuthURI
      • getServerSideGraphQLClients
      • graphqlHandler
      • krakenOAuthHandler
      • loginHandler
      • updateOrgTokenHandler
    const defaultKrakenConfig = {
    authEndpoint: process.env.KRAKEN_AUTH_ENDPOINT,
    graphqlEndpoint: process.env.KRAKEN_GRAPHQL_ENDPOINT,
    oauthClientId: process.env.KRAKEN_OAUTH_CLIENT_ID,
    organizationSecretKey: process.env.KRAKEN_ORGANIZATION_KEY,
    xClientIpSecretKey: process.env.KRAKEN_X_CLIENT_IP_SECRET_KEY,
    };

    Similarly, the edgeConfig and encryption configuration options are now derived from environment variables in getServerSideGraphQLClients and updateOrgTokenHandler.

    const defaultEdgeConfig = {
    envVar: process.env.EDGE_CONFIG,
    teamId: process.env.VERCEL_TEAM_ID,
    authToken: process.env.VERCEL_AUTH_TOKEN,
    };

    const defaultEncryptionConfig = {
    key: process.env.AUTH_ENCRYPTION_KEY,
    iv: process.env.AUTH_ENCRYPTION_IV,
    };
  • 61bc194: The package has been split into multiple sub-modules.

    Exports general-purpose constants and types.

    import {
    TOKEN_COOKIE_KEYS,
    krakenAuthTokenOverrideHeader,
    rawCookiesHeader,
    xClientIpAuthorizationHeader,
    xClientIpHeader,
    sessionQueryKey,
    ignoredQueryParams,
    nextPageParam,
    type CookieKey,
    type CookieMap,
    type CookieName,
    type AuthScope,
    type EdgeConfig,
    type EncryptionConfig,
    type KrakenConfig,
    type AuthHandlers,
    type SessionData,
    } from "@krakentech/blueprint-auth";

    Exports client-side hooks and context providers.

      import {
    AppProvider,
    useAuth,
    useGraphQLClient
    useKrakenAuthErrorHandler,
    useLogin,
    useLogout,
    useSession,
    - } from '@krakentech/blueprint-auth'
    + } from '@krakentech/blueprint-auth/client'

    Exports the middleware handler.

      import {
    authMiddleware,
    type AuthMiddlewareProps,
    - } from '@krakentech/blueprint-auth'
    + } from '@krakentech/blueprint-auth/middleware'

    Export server-side utility functions and API handlers.

      import {
    createKrakenOAuthURI,
    getServerSideGraphQLClients,
    getSessionData,
    graphqlHandler,
    krakenOAuthHandler,
    loginHandler,
    logoutHandler,
    prefetchSession,
    sessionHandler,
    updateOrgTokHandler,
    type AuthenticatedGraphQLClient,
    type GetServerSideGraphQLClientsConfigOptions,
    type GetServerSideGraphQLClientsArgs,
    type getServerSideGraphQLClientsContext,
    type ObtainKrakenToken,
    - } from '@krakentech/blueprint-auth'
    + } from '@krakentech/blueprint-auth/server'

    Exports utility functions.

    import {
    createAuthCookieUtils,
    setKrakenAuthTokenOverrideHeader,
    setNextPageSearchParam,
    - } from '@krakentech/blueprint-auth'
    + } from '@krakentech/blueprint-auth/utils'

    Exports the webpack plugin.

    import {
    withBlueprintAuth,
    - } from '@krakentech/blueprint-auth'
    + } from '@krakentech/blueprint-auth/webpack'

Minor Changes​

  • 2b03696: Allow auth-scope dependent custom-headers on server-side GraphQL clients.

    The setCustomHeaders callback of getServerSideGraphQLClients takes an additional authScope: 'user' | 'organization' parameter, allowing consumers to conditionally set headers.

    const { userScopedGraphQLClient, orgrnizationScopedGraphQLClient } =
    getServerSideGraphQLClients({
    setCustomHeaders(headers, scope) {
    switch (scope) {
    case "user": {
    return headers.set("x-custom-header", "foo");
    }
    case "organization": {
    return headers.set("x-custom-header", "bar");
    }
    }
    },
    });
  • 25c7dee: The new krakenConfig.graphqlAuthEndpoint can be used to target a different GraphQL API endpoint for all internal authentication operations. This is useful when using a back-end delegating authentication to Kraken.

    This can be configured by setting the KRAKEN_GRAPHQL_AUTH_ENDPOINT environment variable, or by providing the option to:

    • authMiddleware
    • getServerSideGraphQLClients
    • graphqlHandler
    • loginHandler
    • updateOrgTokenHandler
    const { userScopedGraphQLClient } = getServerSideGraphQLClients({
    context,
    config: {
    krakenConfig: {
    graphqlEndpoint: "https://api.your-brand.energy/v1/graphql/",
    graphqlAuthEndpoint: "https://api.your-kraken-auth.energy/v1/graphql/",
    },
    },
    });

25.1.0​

Minor Changes​

  • 9c24225: Use DeepPartial type for mock data

25.0.3​

Patch Changes​

  • 8734fdd: ## @krakentech/blueprint-auth

    • Reset session query after logout. This means that the isAuthenticated prop from the useSession hook returns an updated value on logout.

    @krakentech/chat-bot​

    • Implement chatbot feature so that it actually calls the APIs. See the gb-energy-consumer-site for an example of how to implement it.

25.0.2​

Patch Changes​

  • 45653b2: Import useRouter from next/compat/router instead of next/router to ensure compatibility.

25.0.1​

Patch Changes​

  • 5acadcc: Import useRouter from next/compat/router

25.0.0​

Major Changes​

  • d580b2f: useSession: return the full useQuery object instead of destructured data object. This change is to provide more flexibility to the consumer to handle the loading and error states and to align with best practices.

    - const { isAuthenticated, isMasquerading, isMobileWebView, sub } = useSession();
    + const { data: { isAuthenticated, isMasquerading, isMobileWebView, sub }, isLoading, isError, ... } = useSession();

Patch Changes​

  • Updated dependencies [d580b2f]
    • @krakentech/blueprint-api@0.6.0

24.0.3​

Patch Changes​

24.0.2​

Patch Changes​

  • 3c29cde: Create tsup.config file and mark react/react-dom as externals
  • Updated dependencies [3c29cde]
    • @krakentech/blueprint-api@0.5.1

24.0.1​

Patch Changes​

  • c62e1fb: Read Set-Cookie headers from rawHeaders in getAuthCookies.

24.0.0​

Major Changes​

  • 4ee7bd5: What changed?

    • getServerSideOnlyGraphQLOrgClient has been removed, you should now use getServerSideGraphQLClients instead.
    • getServerSideGraphQLClients was revamped from the ground up, it now performs requests against the Kraken GraphQL API directly, without going through the /api/graphql API first. The new implementation builds on top of getServerSideOnlyGraphQLOrgClient and replaces it.

    Migration guide

    • If you're NOT using getServerSideOnlyGraphQLOrgClient or getServerSideGraphQLClients:

    You don't need to do anything! 🎉

    • If you're using getServerSideOnlyGraphQLOrgClient:

    getServerSideOnlyGraphQLOrgClient can be replaced by getServerSideGraphQLClients. It now accepts additional options, such as setCustomHeaders and useSecureCookie, but the functions are compatible:

      import {
    - getServerSideOnlyOrgGraphQLClient,
    + getServerSideGraphQLClients,
    } from '@krakentech/blueprint-auth';
    - const { organizationScopedGraphQLClient } = getServerSideOnlyGraphQLOrgClient({
    + const { organizationScopedGraphQLClient } = getServerSideGraphQLClients({
    • If you're using getServerSideGraphQLClients:

    The graphqlApiRoute parameter was renamed krakenGraphqlApiRoute to make the change explicit:

      const { userScopedGraphQLClient, organizationScopedGraphQLClient } = getServerSideGraphQLClients({
    - graphqlApiRoute: `${getVercelOrigin()}/api/graphql`,
    + krakenGraphqlApiRoute: "https://api.clientcode-kraken.energy/v1/graphql/",
    context,
    })

    The return type was changed from GraphQLClient to AuthenticatedGraphQLClient, you may need to change or replace types in functions handling server-side GraphQL client instances:

      function agreementQueryOptions(
    - client: GraphQLClient,
    + client: GraphQLClient | AuthenticatedGraphQLClient,
    variables: VariablesOf<typeof AgreementQuery>
    ) { ... }

    The new implementation uses the same environment variables you've probably already using for the /api/graphql handler:

    • Vercel EdgeConfig store:
      • EDGE_CONFIG
      • VERCEL_TEAM_ID
      • VERCEL_AUTH_TOKEN
    • Encryption:
      • AUTH_ENCRYPTION_KEY
      • AUTH_ENCRYPTION_IV
    • Kraken:
      • KRAKEN_ORGANIZATION_KEY
      • KRAKEN_X_CLIENT_IP_SECRET_KEY

    However, in case you're using custom names or need to override those values, you could provide the configuration explicitly as well. Here is how environment variables and configuration options map with each other:

    const { userScopedGraphQLClient, organizationScopedGraphQLClient } =
    getServerSideGraphQLClients({
    krakenGraphqlApiRoute: "https://api.clientcode-kraken.energy/v1/graphql/",
    context,
    config: {
    krakenConfig: {
    organizationSecretKey: process.env.KRAKEN_ORGANIZATION_KEY,
    xClientIpSecretKey: process.env.KRAKEN_X_CLIENT_IP_SECRET_KEY,
    },
    edgeConfig: {
    envVar: process.env.EDGE_CONFIG,
    teamId: process.env.VERCEL_TEAM_ID,
    authToken: process.env.VERCEL_AUTH_TOKEN,
    },
    encryption: {
    key: process.env.AUTH_ENCRYPTION_KEY,
    iv: process.env.AUTH_ENCRYPTION_IV,
    },
    },
    });

    The configuration object also has two fields that do not map to environment variables, if you need them then they should look familiar:

    const { userScopedGraphQLClient, organizationScopedGraphQLClient } =
    getServerSideGraphQLClients({
    krakenGraphqlApiRoute: "https://api.clientcode-kraken.energy/v1/graphql/",
    context,
    config: {
    // optional, default: true, set to false during tests if you need to access cookie values
    useSecureCookie: process.env.NODE_ENV === "test",
    // optional, set custom headers for every request made with the client instance
    setCustomHeaders(headers) {
    headers.set("x-custom-header", "my-custom-header-value");
    },
    },
    });

23.1.0​

Minor Changes​

  • 27d2201: graphqlHandler: return an error if the request has no query in its body.

23.0.0​

Major Changes​

  • 3107a9a: Remove the /server submodule since there's currently an issue when using it together with Vitest.

    The initial motivation behind this change was so that consumers could upgrade to Next.js v15 without any issues but we'll have to first figure out how to make the /server submodule work together with Vitest.

    We're reverting this change for now so that we can push other changes to the auth package.

     import {
    authMiddleware,
    getServerSideGraphQLClients,
    getServerSideOnlyOrgGraphQLClient,
    getSessionData,
    graphqlHandler,
    krakenOAuthHandler,
    loginHandler,
    logoutHandler,
    sessionHandler,
    updateOrgTokenHandler
    - } from '@krakentech/blueprint-auth/server';
    + } from '@krakentech/blueprint-auth';

22.0.0​

Major Changes​

  • 7e16955: getSessionData data is now available on the /server submodule.

    - import { getSessionData } from '@krakentech/blueprint-auth';
    + import { getSessionData } from '@krakentech/blueprint-auth/server';

21.0.1​

Patch Changes​

  • f243619: Add more logging to getServerSideOnlyGraphQLClient

21.0.0​

Major Changes​

  • cdfde0d: Separate client and server code by moving every api route handler and the middleware handler into a /server submodule. This is specially useful for consumers that are looking to bump next to v15. Without this, the consumer would be greated with compilation errors due to the fact that, for example, we would have references to client code (createContext, useContext, etc) in the server code.

     import {
    authMiddleware,
    getServerSideGraphQLClients,
    getServerSideOnlyOrgGraphQLClient,
    getSessionData,
    graphqlHandler,
    krakenOAuthHandler,
    loginHandler,
    logoutHandler,
    sessionHandler,
    updateOrgTokenHandler
    - } from '@krakentech/blueprint-auth';
    + } from '@krakentech/blueprint-auth/server';

20.2.1​

Patch Changes​

  • 5c028e4: Improve getServerSideOnlyOrgGraphQLClient config validation logs.

20.2.0​

Minor Changes​

  • f4cefa4: graphqlHandler: prevent mutations whenever the app is being ran locally (dev mode) + pointing to a production kraken graphql endpoint. This is to prevent accidental mutations to the production database.

20.1.0​

Minor Changes​

  • 1b105b1: ## What's changed?

    This change introduces a new function - getServerSideOnlyOrgGraphQLClient, which returns an object with a property organizationScopedGraphQLClient. This is designed to:

    1. Replace the organizationScopedGraphQLClient in getServerSideGraphQLClients
    2. essentially replace from organizationScopedGraphQLClient in useGraphQLClients.

    Both of these existing approaches have been deprecated. We say essentially in 2. because, it's not a direct replacement - the practice of making organisation scoped requests from the client (where the client gets to define the request and the variables) is fundamentally insecure. All requests made to organisation scoped mutations or queries should be made from the server directly to the API. This is what is accomplished with our new hook and client.

    How do I upgrade?​

    Requests currently made on the server​

    Here is a diff of a code example to explain a simple replacement on a server side call

    import {
    - getServerSideGraphQLClients,
    + getServerSideOnlyOrgGraphQLClient
    } from '@krakentech/blueprint-auth';


    const thirdPartyViewerQuery = gql`
    query {
    thirdPartyViewer {
    name
    }
    }
    `;


    const Page = ({
    thirdPartyViewerData,
    }: {
    thirdPartyViewerData: ThirdPartyViewerData;
    }) => {
    return (
    <Stack flexDirection="column" gap="sm">
    <Typography>
    Third Party Viewer: {thirdPartyViewerData.thirdPartyViewer.name}{' '}
    <i>(org scoped request)</i>
    </Typography>
    </Stack>
    );
    };

    export const getServerSideProps: GetServerSideProps = async (context) => {


    - const { organizationScopedGraphQLClient } =
    - getServerSideGraphQLClients({
    - graphqlApiRoute: 'https://localhost:3000/api/graphql/',
    - context,
    - });

    + const { organizationScopedGraphQLClient } =
    + await getServerSideOnlyOrgGraphQLClient({
    + krakenGraphqlApiUrl: 'https://api.clientcode-kraken.energy/v1/graphql/',
    + context,
    + config,
    + });
    + }

    const thirdPartyViewerData =
    await organizationScopedGraphQLClient.request(
    thirdPartyViewerQuery
    );

    return {
    thirdPartyViewerData,
    };

    What will be a bit more involved is replacing client side requests. Let's discuss why:

    Client side queries​

    This one isn't too bad - you can replace a client side query with a server side query in getServerSideProps or getStaticProps. As a rule of thumb, it probably makes more sense to use getServerSideProps since otherwise we could end up displaying stale data.

    Client side mutations​

    This one is more complicated. Let's use the example of createAccount at the end of the join process. We want to call this on form submit, so it feels like we need to call it on the client side. However, this exposes this request to the client and let's anyone call this with any values. If that was acceptable, we should probably remove the organisation authentication all together and just use standard rate limiting - which there is precedence for - see slack discussion and example Kraken core PR.

    If organisation authentication is required for a mutation, we need to make a custom local API endpoint, which exposes only the specific mutation and appropriate input fields. Here is an example.

    import type { NextApiRequest, NextApiResponse } from "next";

    import { SelectProductsMutation } from "@/src/features/onboarding/graphql/mutations/select-products";
    import {
    getKrakenErrorDetails,
    isKrakenErrorResponse,
    } from "@krakentech/blueprint-api";
    import { withSentry } from "@sentry/nextjs";

    import { getServerSideGraphQLClient } from "../../lib/graphql/server-org-client";

    export const config = {
    api: {
    externalResolver: true,
    },
    };

    export class APIURLError extends Error {
    APIURL;

    constructor(msg: string, APIURL: string) {
    super(`${msg}, APIURL: ${APIURL}`);
    // Set the prototype explicitly.
    Object.setPrototypeOf(this, APIURLError.prototype);
    this.APIURL = APIURL;
    }
    }

    const handler = async (req: NextApiRequest, res: NextApiResponse) => {
    // Verify that the request method is POST
    if (req.method !== "POST") {
    res.status(405).end();
    return;
    }

    try {
    const body = JSON.parse(req.body);
    const quoteCode = body.quoteCode as string;
    const selectedQuotedProductIds =
    body.selectedQuotedProductIds as string[];

    const { organizationScopedGraphQLClient } =
    await getServerSideGraphQLClient();

    const response = await organizationScopedGraphQLClient.request(
    SelectProductsMutation,
    {
    input: {
    quoteCode,
    selectedQuotedProductIds,
    },
    }
    );
    res
    .status(200)
    .setHeader(
    "Cache-Control",
    "no-cache, no-store, max-age=0, must-revalidate"
    )
    .json(response);
    } catch (error) {
    if (error instanceof APIURLError) {
    res.status(400).json({ data: null, errors: [error] });

    return;
    }

    // Type guard to check if the error is a Kraken error response
    if (!isKrakenErrorResponse(error)) {
    res.status(400).json({ data: null, errors: [error] });

    return;
    }

    // Error is krakenErrorResponse type
    const [firstError] = error.response.errors;
    const { errorDescription, errorCode } = getKrakenErrorDetails(firstError);

    const errors = [{ errorDescription, errorCode }];

    res.status(400).json({
    data: null,
    errors,
    });
    }
    };

    export default withSentry(handler);

    You can then call that API endpoint in client side code using something like this:

    const response = await fetch(`/api/select-products`, {
    method: "POST",
    body: JSON.stringify({
    quoteCode: data.quoteRequest.code,
    selectedQuotedProductIds: filteredOffering.products.map(
    (product) => product.id
    ),
    }),
    });
    await response.json();

    Configuration options for the client​

    The values here are the defaults set by Blueprint - if you set these values in your env file they will get picked up automatically, or you can pass them in explicitly.

    const config: KrakenOrgConfigOptions = {
    krakenConfig: {
    // the secret key for the organisation you want to authenticate as
    organizationSecretKey: process.env.KRAKEN_ORGANIZATION_KEY,
    // the secret key used for your kraken to override the ip address for requests for rate limiting purposes
    xClientIpSecretKey: process.env.KRAKEN_X_CLIENT_IP_SECRET_KEY,
    // a value to use to override the x-client-ip address passed to Kraken.
    // This is useful if your build process or e2e tests are getting rate limited by a localhost ip address.
    xClientIpOverride: "",
    },
    edgeConfig: {
    // edge config string for the project, used for caching encrypted org tokens
    envVar: process.env.EDGE_CONFIG,
    // vercel team id
    teamId: process.env.VERCEL_TEAM_ID,
    // vercel auth token
    authToken: process.env.VERCEL_AUTH_TOKEN,
    },
    encryption: {
    // the encryption key used to encrypt the cached org tokens
    key: process.env.AUTH_ENCRYPTION_KEY,
    // the IV used to encrypt the cached org tokens
    iv: process.env.AUTH_ENCRYPTION_IV,
    },
    };

20.0.0​

Patch Changes​

  • Updated dependencies [ebf8ae7]
    • @krakentech/blueprint-api@0.5.0

19.0.0​

Major Changes​

  • a76860e: authMiddleware: change the res prop to expect a NextResponse instead of typeof NextResponse. This way the user can pass a custom NextResponse instance and this middleware utility fn won't have to be the first one in the chain.

    import { NextResponse } from 'next/server';

    await authMiddleware({
    req,
    - res: NextResponse,
    + res: NextResponse.next(), // or a custom NextResponse coming from another utility fn, for example.
    ...

18.3.0​

Minor Changes​

  • d7e7514: Export getSessionData fn so that consumers can use it to retrieve session data server-side

18.2.0​

Minor Changes​

  • 0097446: useLogin: add a shouldRedirectToNextPage prop so that consumers can disable the default behaviour of redirecting to the page in the nextPage query parameter after login (or the AuthProvider.appRoutes.dashboard as a fallback). It's true by default.

18.1.0​

Minor Changes​

  • 8cd8c49: sessionHandler + useSession: isAuthenticated is now true if the MWAuthToken cookie is set (by Flapjack) and return an additional isMobileWebView when it is as well so that consumers can conditionally renders parts of the app if the user is seeing the website through a mobile WebView.

18.0.1​

Patch Changes​

  • 90aef5a: Refactor and rename isValidURL function and its usages.

    Rename isValidUrl -> validateURL

    validateURL returns an object {valid: boolean, error?: Error}

18.0.0​

Major Changes​

  • 0e45b12: - Refactored setKrakenAuthTokenOverrideHeader to accept headers as a prop

    • Now accepts headers object as a prop

    Update all setKrakenAuthTokenOverrideHeader:

    //Before
    setKrakenAuthTokenOverrideHeader(token);

    // After
    const headers = new Headers();
    setKrakenAuthTokenOverrideHeader({ token, headers });

17.0.0​

Major Changes​

  • 3a618e1: authMiddleware: change the way we pass in props related to the appRoutes in order to allow further route specific configurations.

    • The anon, masquerade and dashboard routes now support a custom success/error responses.
    • Previously we had a bunch of properties that were related to a single app route at the root of the authMiddleware props and now they are nested under their respective appRoutes key. For example: getPreSignedKey to appRoutes.anon.getPreSignedKey.

    Before​

    {
    appRoutes: {
    anon: '/anon',
    dashboard: '/dashboard',
    login: '/login',
    masquerade: '/masquerade',
    },
    dashboardRouteAllowList: [...],
    getPreSignedKey: () => {},
    getUserIdAndMasqueradeToken: () => {},
    }

    After​

    appRoutes: {
    anon: {
    path: '/anon',
    getPreSignedKey: () => {},
    customSuccessResponse: () => {},
    customErrorResponse: () => {},
    },
    dashboard: {
    path: '/dashboard',
    allowList: [...],
    customSuccessResponse: () => {},
    customErrorResponse: () => {},
    },
    login: {
    path: '/login',
    },
    masquerade: {
    path: '/masquerade',
    getUserIdAndMasqueradeToken: () => {},
    customSuccessResponse: () => {},
    customErrorResponse: () => {},
    },
    },

16.5.0​

Minor Changes​

  • 4195e36: authMiddleware: support authenticated webviews. If the MWAuthToken cookie is present, the user can now navigate to a protected route (usually dashboard pages) and if they try to access the login page, they will be redirected to the dashboard page.

Patch Changes​

  • aa5d908: Remove sub, authProvider cookies when there is no refreshToken

16.4.0​

Minor Changes​

  • b623770: redirectToNextPage: do not redirect anywhere if both the nextPage url search param is invalid or the fallback isn't provided.

    Export nextPageParam as a named export so that consumers can use it to create their own custom redirects.

16.3.0​

Minor Changes​

  • 8ce59bc: authMiddleware: support additional url search params when handling the "nextPage". Now if the user tries to go to a protected route, say, /dashboard/accounts/A-123456?referralCode=123 while unauthenticated, the user will still be redirected to the login page and after successful login, the user will be redirected to the original URL with the search params intact.

    Before: /dashboard/accounts/A-123456?referralCode=123 -> /login?nextPage=/dashboard/accounts/A-123456 -> /dashboard/accounts/A-123456 After: /dashboard/accounts/A-123456?referralCode=123 -> /login?nextPage=/dashboard/accounts/A-123456&referralCode=123 -> /dashboard/accounts/A-123456?referralCode=123

16.2.2​

Patch Changes​

  • 5cab6d6: authMiddleware: only redirect users that navigate to the /login page to the /dashboard if they are "truly" authenticated, essentially if both the refresh and access tokens are stored in cookies.

16.2.1​

Patch Changes​

  • 7c045a7: graphqlHandler: only check for query operation definitions (instead of checking for fragment definitions as well) to determine if a query operation is allowed to be executed whenever the request is meant to be org scoped. This is to prevent the graphqlHandler from blocking queries that contain fragment definitions.

16.2.0​

Minor Changes​

  • 3a548f1: graphqlHandler: add allowedOrganizationScopedOperations prop. This change allows consumers to specify which operations are allowed to be organization scoped.

16.1.5​

Patch Changes​

  • c8f5124: updateOrgTokenHandler: return meaningfull error status codes and log errors:

    • 401 if the CRON_SECRET env var is not set
    • 500 if the either the ObtainKrakenToken mutation fails or the PATCH request (to update the org token in the project's Edge Config Store) to Vercel's API fails

16.1.4​

Patch Changes​

  • 62348cc: updateOrgTokenHandler: properly handle errors coming from Vercel's API requests so that we are able to debug errors in the future

    Add a bunch of logs to the authMiddleware and the other api route handlers error states in order to facilitate debugging in the future.

16.1.3​

Patch Changes​

  • 35a249b: graphqlHandler: in production, fallback to fetching a new organization token from Kraken if the organization token is either missing or expired (in the Edge Config). Previously we were (also) trying to update the token in the Edge Config, but it turns out that it can be quite tricky to do so if a lot of users are trying to access the service at the same time. This change should make the service more resilient to token expiration issues.

16.1.2​

Patch Changes​

  • 0f8e270: Improve server error logs by always passing the error itself

16.1.1​

Patch Changes​

  • 2fa0ba6: Update Next to latest minor version

16.1.0​

Minor Changes​

  • 3705584: ### Summary of Changes

    • Implemented OAuth Refresh Token Flow: Added middleware and specifications to handle the OAuth refresh token flow, ensuring access tokens are refreshed automatically.
    • Enhanced Error Handling: Introduced an onError handler to manage errors during the token refresh process and ensure proper cleanup of cookies.
    • Updated Cookie Management: Added the authProvider cookie to various flows (standard login, masquerade login and oAuth login) to track and manage authentication providers.
    • Extended Configuration: Introduced new properties to the krakenConfig for configuration management of oAuth.
    • Improved Schema Validation: Enhanced the schema with an optional error property to handle error scenarios more gracefully.
    • Cleaned Up Codebase: Removed unnecessary oauthClientSecret usages.

16.0.0​

Major Changes​

  • fb46a39: It's only a major bump because you need to provide a new appRoute.dashboard to the AuthProvider.

    With these changes, you no longer have to add redirect logic to your login route. If the user is already authenticated and tries to go to the login route, they will be redirected to the nextPage url if there is one (and it's valid), otherwise they will be redirected to the dashboard. The redirect logic has been also added to the on the onSucces callback of the useLogin hook for your convenience as well.

15.2.0​

Minor Changes​

  • 697774b: Turn the AuthProvider.handlers prop optional and provide a default onLoginError implementation that redirects the user to the same page with an error query parameter.

15.1.0​

Minor Changes​

  • c82d066: Create url related helpers so that consumers can redirect users to the page in the nextPage param safely:

    • redirectToNextPage - Redirects to the page in the nextPage param if it is a valid URL by sanitizing it.
    • setNextPageSearchParam - Sets the nextPage search param in the URL in you need it manually in your app.

15.0.0​

Patch Changes​

  • ac9cc96: Fix useLogin hook so that the onSuccess and onError callbacks are called correctly
  • Updated dependencies [66a8c3f]
    • @krakentech/blueprint-api@0.4.0

14.0.1​

Patch Changes​

  • 8a4ff09: Updates Typescript and adds noUncheckedIndexedAccess rule to utils package

14.0.0​

Major Changes​

  • 3e711cf: In order to make it more clear where to use the getGraphQLClient function, it has been renamed to getServerSideGraphQLClients and it returns a userScopedGraphQLClient and organizationScopedGraphQLClient, much like the useGraphQLClients hook (which is meant to be used client-side).

    This means that, if you weren't using the getGraphQLClient function, you don't have to do anything.

13.0.0​

Major Changes​

  • 88bea42: > This is only a "major" release if you're making organization scoped requests to the Kraken API. If you're only making user scoped requests, you don't have to do anything.

    Persist the organization token in Vercel's edge config instead of cookies so that every user's session can use the same token to make requests to the organization's GraphQL API. This will make it virtually impossible to hit the rate limit surrounding the obtainKrakenToken mutation.

    Required changes:

    • The graphqlHandler requires a new edgeConfig property.
    • Creating a new API route to handle the periodic updates of the organization token in the edge config that uses the updateOrgTokenHandler function.
    • Adding it to the vercel.json crons array and set it to run every X minutes where X is the token's expiration time minus a few minutes. (e.g. 55 minutes for a 1-hour token)
    • Create or connect to a Edge Config Store in your Vercel project. -> https://vercel.com/<team-id>/<project-id>/stores

    There's more detailed information in the blueprint-auth documentation.

12.1.0​

Minor Changes​

  • 70234a2: Add the x-client-ip-authorization header to every server request (if provided). This header is used by Kraken to prevent valid server-side requests, which originate from a single/pool of IPs (this will be the case if you host your app in Vercel for example), from being erroneously rate-limited. More information can be found on this Kraken announcement.

    If you want this header to be set, you need to pass in a krakenConfig.xClientIpSecretKey to the graphqlHandler, loginHandler and authMiddleware functions.

12.0.1​

Patch Changes​

  • 71aaf73: Retry organization scoped requests if we use an invalid/expired token as the auth header value
  • a715956: Fix the createEncryptionUtils so that they don't return an error if the encryption/decryption fails for some reason (if the key/iv pair used to decrypt a token is different than the one used to encrypt it, for example)
  • 96d702e: Make the getAuthToken usable in both middleware and api routes

12.0.0​

Major Changes​

  • 931f912: Upgrade to react-query 5

11.0.0​

Major Changes​

  • bfa2843: - Remove support for relative paths in the getGraphQLClient function. The reason being: react's first render happens on the server where window is undefined. This means that consumers would either have to pass an absolute path anyway or wrap the client in a useEffect which is less than ideal.
    • Create a new useGraphQLClients hook that returns authenticated kraken graphql clients for client-side use.
    • The AuthProvider requires a new apiRoute.graphql prop which is the path to the graphql endpoint. This is required for the useGraphQLClients hook to work.

10.0.2​

Patch Changes​

  • 3e8dd70: Fix getAuthToken function: previously it doesn't didn't return the correct authToken in preview/prod deployments

10.0.1​

Patch Changes​

  • 0500d69: Fix the way we determine which token we pass to the auth header when the request is made on the server (getServerSideProps)

10.0.0​

Major Changes​

  • 5baa598: - Remove the getOrganizationScopedGraphQLClient function in favor of having a single getGraphQLClient function that takes a scope argument to choose between organization and user scoped clients.
    • Assert the origin of the url automatically when used on the client or in getServerSideProps. This means that you only have to pass a relative path to the graphqlApiRoute prop of the getGraphQLClient function. http://localhost:3000/api/graphql -> /api/graphql essentially.
    • getGraphQLClient now requires the context to be passed instead of just the req object when used server-side.

9.5.2​

Patch Changes​

  • 09e2ee0: Make both graphql helpers (getGraphQLClient and getOrganizationGraphQLClient) use the automatically set (by Vercel)VERCEL_AUTOMATION_BYPASS_SECRET environment variable to bypass the authentication check instead of requiring consumers to manually create and maintain a NEXT_PUBLIC_VERCEL_AUTOMATION_BYPASS_SECRET environment variable.

9.5.1​

Patch Changes​

  • 5f66908: Make getGraphQLClient req prop optional so that it can be used on the client without type errors

9.5.0​

Minor Changes​

  • 941744c: Refresh access token when we get a token invalid error

9.4.1​

Patch Changes​

  • b71a990: Remove errors array from our api responses so that we return success responses the same way Kraken does

9.4.0​

Minor Changes​

  • 1e086a3: Add useKrakenAuthErrorHandler hook to auth package

9.3.0​

Minor Changes​

  • 4025416: Persist the (encrypted) organization token so that apps don't need to get a token everytime they need to make organization scoped requests

9.2.1​

Patch Changes​

  • a2ed98e: Allow auth header override for edge cases where the consumer can't adhere to the "normal" way of authenticating requests (this can happen specially due to backend constraints)

9.2.0​

Minor Changes​

  • 702ca06: Add handling for EXPIRED_REFRESH_TOKEN error in API. We found this was missing following an API change which expired tokens early when an email address or password is changed. Previously the cookie which held the refresh token would disappear when the token expired in a more predictable way.

9.1.0​

Minor Changes​

  • dc658fd: Make our graphql client helpers bypass Vercel Deployment Protection

Patch Changes​

  • dc658fd: getOrganizationScopedGraphQLClient: use a custom header (x-kraken-organization-scoped-request) instead of a cookie since we can't set cookies on the client. Error: Refused to set unsafe header "set-cookie"
  • b956213: Fix login error responses to include errors in expected format and returns full errors from graphql API from graphqlHandler;

9.0.0​

Major Changes​

  • dd4867f: Improve organization scoped requests. Some prop naming changes for better clarity/consistency among the api route/middleware handlers:

    • krakenGraphqlEndpoint -> krakenConfig: { graphqlEndpoint }
    • the graphqlHandler now requires an organizationSecretKey -> krakenConfig: { graphqlEndpoint, organizationSecretKey }
    • the getOrganizationScopedGraphQLClient no longer needs the krakenConfig object to be passed in

8.0.0​

Major Changes​

  • 163ffa8: Consistency improvemets, these shouldn't affect anyone but they might if you were using the scopedKrakenToken cookie key for example:

    • Standardized the naming of the cookie keys. Essentially renamed scopedKrakenToken to scopedToken since this was the only cookie that was using the Kraken prefix.
    • Standardized json responses for all the endpoints, now all the endpoints will return a json response with the same structure. (data and errors and will always have a 200 status code like every graphql response)

Patch Changes​

  • 2cd1b7c: Remove hashing of the sub cookie value

7.3.0​

Minor Changes​

  • b05ed44: Added possibility to pass through the client request header

7.2.0​

Minor Changes​

  • 789206c: Add dashboardRouteAllowList prop to authMiddleware. This prop makes it possible for consumers to bypass the dashboard route guarding. This is useful when you need to allow access to pages that live inside the dashboard folder without requiring the user to be authenticated. Without this, the authMiddleware would redirect the user to the login page (if they are not authenticated) instead.

7.1.0​

Minor Changes​

  • a84f02a: Support authenticated WebViews by checking if there is a MWAuthToken present within the request
  • be3a9c9: Add getGraphQLClient and getOrganizationScopedGraphQLClient so that consumers can make server side requests more easily

Patch Changes​

  • be3a9c9: Rename obtainKrakenTokenQuery to obtainKrakenTokenMutation since it is a mutation not a query

7.0.0​

Patch Changes​

  • Updated dependencies [8bda073]
    • @krakentech/blueprint-api@0.3.0

6.0.0​

Major Changes​

  • 85b8ab3: Rename props so it's more clear what is what

    • authMiddleware: graphqlEndpoint -> krakenGraphqlEndpoint
    • authMiddleware: routes -> appRoutes
    • krakenOAuthHandler: removed redirectUri and tokenUri
    • krakenOAuthHandler: added krakenConfig object with authEndpoint, clientId and clientSecret
    • krakenOAuthHandler: added appRoutes object with login, logout and krakenOAuth. These are used to handle the request, and its error/success redirect responses

5.0.0​

Patch Changes​

  • Updated dependencies [a0bd6b8]
    • @krakentech/blueprint-api@0.2.0

4.1.0​

Minor Changes​

  • b9e6a8e: Unify redirect url params, we now add a single "error" url param with either the errorCode we get from Kraken or a sensible fallback.

4.0.1​

Patch Changes​

  • f6d4291: Fix kraken-oauth api handler by adding return

4.0.0​

Major Changes​

  • 3697d07: Remove /dist/middleware submodule, consumers can import the authMiddleware function directly from '@krakentech/blueprint-auth'

Minor Changes​

  • fb8e049: Add Kraken OAuth to auth package

3.0.0​

Patch Changes​

  • Updated dependencies [c5c0279]
    • @krakentech/blueprint-api@0.1.0

2.0.0​

Patch Changes​

  • Updated dependencies [c19dadc]
    • @krakentech/blueprint-utils@1.0.0

1.0.1​

Patch Changes​

  • 3e6520f: Prevent getAuthToken from returning early with an empty string

1.0.0​

Patch Changes​

  • fa19fd0: Support cookies from the server (cookies set by middleware in serverSideProps are still in the set-cookie header instead of the cookie header)
  • 35ff94a: Add seperate @blueprint/utils modules for stripe and i18n
  • Updated dependencies [35ff94a]
    • @krakentech/blueprint-utils@0.3.0

0.3.2​

Patch Changes​

  • 583d413: Fix typo prefecthSession -> prefetchSession and make the function accept context instead of just the req

0.3.1​

Patch Changes​

  • 203ba07: Create prefetchSession function and allow custom login/portfolio redirect urls

0.3.0​

Minor Changes​

  • 8419c83: Allow null as the preSignedKey value (getPreSignedKey)

0.2.2​

Patch Changes​

  • Updated dependencies [57bbdd9]
    • @krakentech/blueprint-utils@0.2.6

0.2.1​

Patch Changes​

  • 739f0ed: - Make anon routes optional (routes that rely on pre signed keys)
    • Accept an array of anon routes

0.2.0​

Minor Changes​

  • 823b48e: Add graphql api route handler

0.1.1​

Patch Changes​

  • Updated dependencies [a9aa708]
    • @krakentech/blueprint-utils@0.2.5

0.1.0​

Minor Changes​

  • 91e4a2c: First version of the blueprint-auth package. This release includes the following features available as imports:

    • next.config.js helper: withBlueprintAuth (meant to be used in the webpack config of a Next.js app)
    • API Route Handlers: loginHandler, logoutHandler, sessionHandler
    • Middleware: authMiddleware
    • Provider: AuthProvider (provides context for the hooks)
    • Hooks: useLogin, useLogout, useSession