Skip to main content

API reference

New to blueprint-auth?

Check out our getting started guides:

Upgrading from an older version?

See the Migration Guide for breaking changes and upgrade instructions.

Configuration

The utility functions of the package all extend the same interface for static configuration options. This enables the use of a centralized configuration object that can be reused throughout the project.

The package provides a configuration factory, enabling auto-completion and type-checking of the configuration object.


createAuthConfig

Create a config object reusable throughout the project, and set compatible options with environment variables.

Configuration

Required options

Required options with an environment variable alternatives must be provided either via environment variables or directly in the config object.

OptionDescriptionTypeEnvironment variableRequired
krakenConfig.authEndpointKraken auth endpointstringKRAKEN_AUTH_ENDPOINT⚠️ Required to enable Kraken OAuth
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstringKRAKEN_GRAPHQL_AUTH_ENDPOINT❌ Defaults to krakenConfig.graphqlEndpoint
krakenConfig.graphqlEndpointTarget GraphQL endpointstringKRAKEN_GRAPHQL_ENDPOINT
krakenConfig.oauthClientIdKraken OAuth client IDstringKRAKEN_OAUTH_CLIENT_ID⚠️ Required to enable Kraken OAuth
krakenConfig.organizationSecretKeyKraken organization secret keystringKRAKEN_ORGANIZATION_KEY⚠️ Required to enable organization-scoped auth
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstringKRAKEN_X_CLIENT_IP_SECRET_KEY
Rate-limiting prevention

Every request to the Kraken API includes the x-kraken-client-ip-authorization header, which is set with the base 64 encoded value of krakenConfig.xClientIpSecretKey, and the x-kraken-client-ip header which is set with the user IP address.

These headers are used by Kraken to attribute requests made from a limited number of IP addresses, e.g. server-side requests, to the actual user IP address, preventing erroneous rate-limiting. More information can be found on this Kraken announcement.

Security

Make sure your secrets are kept secure and available server-side only:

  • Do not hardcode them in your codebase.
  • Do not use environment variables starting with NEXT_PUBLIC_.

Usage

Somewhere in your project, export the config object returned by createAuthConfig.

lib/auth/config.ts
import { createAuthConfig } from "@krakentech/blueprint-auth/server";

export const authConfig = createAuthConfig({ ... });

Middleware

createAuthMiddleware

The middleware is responsible for protecting routes requiring authentication. It redirects unauthenticated users to the login page, and refreshes expired access tokens when necessary. It also handles masquerade and anonymous authentication.

Edge Runtime compatibility

We expose this function separately to avoid bundling code that is unsupported in Edge Runtime. Learn More.

Configuration

OptionDescriptionTypeEnvironment variableRequired
krakenConfig.authEndpointKraken auth endpointstringKRAKEN_AUTH_ENDPOINT⚠️ Required to enable Kraken OAuth
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstringKRAKEN_GRAPHQL_AUTH_ENDPOINT❌ Defaults to krakenConfig.graphqlEndpoint
krakenConfig.graphqlEndpointTarget GraphQL endpointstringKRAKEN_GRAPHQL_ENDPOINT
krakenConfig.oauthClientIdKraken OAuth client IDstringKRAKEN_OAUTH_CLIENT_ID⚠️ Required to enable Kraken OAuth
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstringKRAKEN_X_CLIENT_IP_SECRET_KEY

Usage

If your Next.js middleware only handles authentication, the function returned by createAuthMiddleware can be exported directly as middleware:

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

export const middleware = createAuthMiddleware(authConfig);

export const config = {
matcher: ["/((?!api|_next|_vercel|.*\\..*).*)"],
};

Server Functions

The package exports Server Functions, which can be used in Next.js server-side execution contexts.

Direct usage or factories

These functions can either be used directly, passing all required configuration and context parameters on each call, or via factories.

Server Function Parameters

Server functions typically accept two separate parameter objects:

  1. Static Configuration: Application settings that rarely change (endpoints, secrets, routes). Pass your authConfig object directly.
  2. Runtime Parameters: Dynamic values for each call (context, user input, etc.)
// direct import: static configuration and runtime parameters required
await login(authConfig, { context, input: { email, password } });

// factory pattern: config pre-filled, only runtimes parameters required
await login({ context, input: { email, password } });

When using factory functions, the config is pre-filled automatically.

Execution environment

Compatibility

Not all functions work in all environments. Use the table below to check compatibility.

FunctionSSGSSRAPI HandlerRoute HandlerServer ComponentServer ActionMiddleware
createAuthCookieUtils
generateKrakenOAuthURI
getOrganizationScopedGraphQLClient
getRequestPathname
getSession
getUserScopedGraphQLClient
login
logout
prefetchSession

The context object

All Server Functions expect a context object, which shape varies depending on the execution context.

type StaticPropsContext = Partial<GetStaticPropsContext> | null;
import type { GetStaticPropsContext } from "next";

export async function getStaticPaths() {
const context = null; // or {}
...
}

export async function getStaticProps(context: GetStaticPropsContext) {
...
}
Server Actions and Server Components

At the TypeScript level, Server Actions and Server Components share the same context type since they use the same Next.js APIs (cookies() and headers()). However, we distinguish them with separate type names:

  • ServerComponentContext - For React Server Components (RSC)
  • ServerActionContext - For Server Actions

This distinction helps clarify where each function can be used, even though the underlying type is identical.


Server Function Factories

Server Functions can be used in three different ways, depending on your particular needs.

MethodDescriptionRecommendationNeeds configurationNeeds context
Direct importImport Server Functions directly from the packageOne-off usage or advanced use cases
Server-Side FactoryCreate Server Functions with configuration pre-filledPages Router
App Router FactoryCreate Server Functions with configuration and context pre-filledApp Router
Full API

Directly imported Server Functions expect: configuration object, context object, and other runtime parameters.

Usage
import {
createAuthCookieUtils,
generateKrakenOAuthURI,
getOrganizationScopedGraphQLClient,
getRequestPathname,
getSession,
getUserScopedGraphQLClient,
login,
logout,
prefetchSession,
} from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

const {
getActiveAuthMethod,
getAuthCookie,
getAuthCookies,
getAuthTokenOverride,
getCookieMapItem,
getRefreshToken,
removeAllCookies,
removeAuthCookies,
removeAuthTokenCookies,
setAuthCookie,
} = createAuthCookieUtils(authConfig, { context });
await generateKrakenOAuthURI(authConfig, { context });
await getRequestPathname({ context });
await getSession({ context });
await login(authConfig, { context, input: { email, password } });
await logout({ context });
await prefetchSession({ context, queryClient });
getOrganizationScopedGraphQLClient(authConfig, { context });
getUserScopedGraphQLClient(authConfig, { context });

generateKrakenOAuthURI

Set the code verifier cookie, and generate a unique URI to initiate the Kraken OAuth flow.

Configuration

OptionDescriptionTypeRequired
krakenConfig.authEndpointKraken auth endpointstring
krakenConfig.oauthClientIdKraken OAuth client IDstring

Parameters

ParameterDescriptionTypeRequired
contextRequest contextServerSidePropsContext | ApiRouteHandlerContext | RouteHandlerContext | ServerActionContext | MiddlewareContext

Output

TypeDescription
stringThe generated Kraken OAuth URI

Usage

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

const krakenOAuthURI = await generateKrakenOAuthURI(authConfig, { context });

getSession

Read session data from cookies.

Configuration

This function does not require static configuration.

Parameters

ParameterDescriptionTypeRequired
contextRequest contextServerSidePropsContext | ApiRouteHandlerContext | RouteHandlerContext | ServerComponentContext | ServerActionContext | MiddlewareContext

Output

Returns a SessionState object:

FieldDescriptionType
authMethodThe active authentication method based on cookie priorityAuthMethod | null
isAuthenticatedUser has an auth token cookieboolean
subThe value of the sub cookie if setstring | null

Usage

const { authMethod, isAuthenticated, sub } = await getSession({ context });

login

Authenticate a user using email and password, and triggers redirect on successful authentication.

Configuration

OptionDescriptionTypeRequired
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstring
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstring

Parameters

ParameterDescriptionTypeRequired
contextRequest contextApiRouteHandlerContext | RouteHandlerContext | ServerActionContext
inputLogin credentials{ email: string; password: string }
nextPageRedirect pathnamestring | null
enableRedirectEnable redirectboolean❌ Only available in API Handlers and Route Handlers
searchParamsThe URL search paramsSearchParams | Promise<SearchParams>❌ Only available in Server Actions

Output

Context dependant output

The return type of this function varies depending on the execution context.

TypeCondition
Promise<undefined>Always

Usage

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

await login(authConfig, {
context,
input: { email: "test@example.com", password: "****" },
nextPage: "/dashboard/settings",
searchParams, // available as props in Next.js App Router page components
});
Redirect behavior

If the nextPage options is not set, the nextPage URL search parameter is used, appRoutes.dashboard.pathname is used as a fallback. To disable redirection, set the nextPage option to null.

API Handlers

Redirection is disabled by default in API Handlers and Route Handlers. To enable redirects, set the enableRedirect option to true.

Learn more

When an fetch request responds a 303 See Other status code, the Pages Router does not trigger a client-side navigation. Instead, the browser handles it and triggers a navigation, losing state in the process.

To accomodate for this limitation of the Pages Router, by default the redirect URL is stored in the response body as a JSON object, and redirection is left to the caller.

However, this behavior does not fit all use cases. For instance, a redirect response is desirable when the API endpoint is used as the action attribute of the HTML <form> element. To enable redirects, set the enableRedirect option. The use of the login function in a Server Action is recommended in the App Router. Check out our Building Forms tutorial to learn more.

Error handling

In case authentication fails, the login Server Function does not redirect to the current URL with the error code as the error URL search parameter.

Learn more

Since Next.js 15, calling redirect in a Server Action results in a 303 See Other status response. The App Router handles this error code with a client-side navigation, preserving the state of layout components. However, redirecting to the same page triggers a full page reload, losing client-side page state in the process.

Handling errors client-side prevents the progressive enhancements enabled by Server Actions. If you're using the App Router, consider storing form errors and validation errors as action state using React's useActionState hook. Check out the Next.js documentation to learn more.


logout

Remove auth cookies, and redirects the user to the home page.

Configuration

OptionDescriptionTypeRequired
appRoutes.home.pathnameHome pathnamestring

Parameters

ParameterDescriptionTypeRequired
contextRequest contextServerSidePropsContext | ApiRouteHandlerContext | RouteHandlerContext | ServerActionContext
nextPageRedirect pathnamestring | null
enableRedirectEnable redirectboolean❌ Only available in API Handlers and Route Handlers

Output

Context dependant output

The return type of this function varies depending on the execution context.

TypeCondition
Promise<undefined>Always

Usage

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

await logout(authConfig, { context, nextPage: "/goodbye" });
Redirect behavior

If the nextPage option is not set, appRoutes.home.pathname is used as the default redirect. To disable redirection, set the nextPage option to null.

API Handlers

Redirection is disabled by default in API Handlers and Route Handlers. To enable redirects, set the enableRedirect option to true.

Learn more

When an fetch request responds a 303 See Other status code, the Pages Router does not trigger a client-side navigation. Instead, the browser handles it and triggers a navigation, losing state in the process.

To accomodate for this limitation of the Pages Router, by default the redirect URL is stored in the response body as a JSON object, and redirection is left to the caller.

However, this behavior does not fit all use cases. For instance, a redirect response is desirable when the API endpoint is used as the action attribute of the HTML <form> element. To enable redirects, set the enableRedirect option. Check out our Building Forms tutorial to learn more.


prefetchSession

Reads session data from the cookie, and stores the result into the QueryClient instance cache.

HydrationBoundary required

prefetchSession must be used in combination with the HydrationBoundary component from @tanstack/react-query. To set it up with the Pages Router, check out the Server Rendering and Hydration guide. To learn more about the App Router setup, check out the Advanced Server Rendering guide.

Configuration

This function does not require static configuration.

Parameters

ParameterDescriptionTypeRequired
contextRequest contextServerComponentContext | ServerSidePropsContext | StaticPropsContext
queryClient@tanstack/react-query client instanceQueryClient

Output

TypeDescription
Promise<void>No return value

Usage

Usage
import { prefetchSession } from "@krakentech/blueprint-auth/server";
import { QueryClient } from "@tanstack/react-query";

const queryClient = new QueryClient();
await prefetchSession({ context, queryClient });

getRequestPathname

Get the pathname from the current request.

Configuration

This function does not require static configuration.

Parameters

ParameterDescriptionTypeRequired
contextRequest contextServerSidePropsContext | ApiRouteHandlerContext | RouteHandlerContext | ServerComponentContext | ServerActionContext | MiddlewareContext

Output

TypeDescription
Promise<string>The current request pathname

Usage

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

const pathname = await getRequestPathname({ context });

getUserScopedGraphQLClient

Create a GraphQL client using user-scoped authentication.

Configuration

OptionDescriptionTypeRequired
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstring
krakenConfig.graphqlEndpointTarget GraphQL endpointstring
krakenConfig.xClientIpOverrideOverride for the user IP header (for tests)string
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstring

Parameters

ParameterDescriptionTypeRequired
contextRequest contextStaticPropsContext | ServerSidePropsContext | ApiRouteHandlerContext | RouteHandlerContext | ServerComponentContext | ServerActionContext | MiddlewareContext
errorPolicyHow the client handles GraphQL errors"none" | "ignore" | "all"

Output

TypeDescription
AuthenticatedGraphQLClientAn authenticated GraphQL client for making requests

Usage

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

const graphQLClient = getUserScopedGraphQLClient(authConfig, { context });
const viewer = await graphQLClient.request(ViewerQuery);
Full API reference

The returned client is an instance of AuthenticatedGraphQLClient. See the Classes section for complete documentation on the request method, error handling, retry behavior, and advanced features.

getOrganizationScopedGraphQLClient

Create a GraphQL client using organization-scoped authentication.

Configuration

OptionDescriptionTypeRequired
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstring
krakenConfig.graphqlEndpointTarget GraphQL endpointstring
krakenConfig.organizationSecretKeyKraken organization secret keystring
krakenConfig.xClientIpOverrideOverride for the user IP header (for tests)string
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstring

Parameters

ParameterDescriptionTypeRequired
contextRequest contextStaticPropsContext | ServerSidePropsContext | ApiRouteHandlerContext | RouteHandlerContext | ServerComponentContext | ServerActionContext | MiddlewareContext
errorPolicyHow the client handles GraphQL errors: "none", "ignore", or "all". See Error policy."none" | "ignore" | "all"

Output

TypeDescription
AuthenticatedGraphQLClientAn authenticated GraphQL client for making requests

Usage

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

const graphQLClient = getOrganizationScopedGraphQLClient(authConfig, {
context,
});
const thirdPartyViewer = await graphQLClient.request(ThirdPartyViewerQuery);
Full API reference

The returned client is an instance of AuthenticatedGraphQLClient. See the Classes section for complete documentation on the request method, error handling, retry behavior, and advanced features.

createAuthCookieUtils

Create helpers to manage authentication cookies.

Configuration

OptionDescriptionTypeRequired
customization.getCookieOptionsCustomize cookie options(cookieName: [CookieName](#cookiename)) => SerializeOptions | undefined

Output

Returns an object with the following fields:

FieldDescriptionType
getActiveAuthMethodDetermine active authentication method based on cookie priority(cookies: [CookieMap](#cookiemap)) => AuthMethod | null
getAuthCookieGet auth cookie(name: [CookieName](#cookiename)) => Promise<string | undefined>
getAuthCookiesGet auth cookie map() => Promise<[CookieMap](#cookiemap)>
getAuthTokenOverrideGet auth token override from request header() => Promise<{ token: string, type: "override" } | null>
getCookieMapItemGet cookie from cookie map<Name extends [CookieName](#cookiename)>({ cookies, name }: { cookies: [CookieMap](#cookiemap), name: Name }) => { type: Name, value: string } | null
getRefreshTokenGet refresh token from cookie() => Promise<string | undefined>
removeAllCookiesRemove all auth cookies() => Promise<void>
removeAuthCookiesRemove auth cookies(cookies: [CookieName](#cookiename)[]) => Promise<void>
removeAuthTokenCookiesRemove auth token cookies, i.e. accessToken, masqueradeToken, MWAuthToken, scopedToken() => Promise<void>
setAuthCookieSet auth cookie({ name, value, expires }: { name: [CookieName](#cookiename), value: string, expires: Date | undefined }) => Promise<void>

See CookieName and CookieMap in the Types section for type definitions.

Usage

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

const {
getActiveAuthMethod,
getAuthCookie,
getAuthCookies,
getAuthTokenOverride,
getCookieMapItem,
getRefreshToken,
removeAllCookies,
removeAuthCookies,
removeAuthTokenCookies,
setAuthCookie,
} = createAuthCookieUtils(authConfig, { context });

API Handlers

The packages exports factory functions to create API handlers. The handlers can be used with the Pages Router as API Handlers, or with the App Router as Route Handlers.

Cache disabled

API handlers the Cache-Control header with no-cache, no-store, max-age=0, must-revalidate", effectively disabling the cache ensure each request results in a fresh response.

createLoginHandler

The login handler authenticates the user using email and password, sets auth cookies, and provides a redirect URL in the response.

Configuration

OptionDescriptionTypeEnvironment variableRequired
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstringKRAKEN_GRAPHQL_AUTH_ENDPOINT
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstringKRAKEN_X_CLIENT_IP_SECRET_KEY

Output

TypeDescription
(req: NextApiRequest, res: NextApiResponse) => Promise<void>Handler function for Pages Router
(req: NextRequest) => Promise<NextResponse<unknown | AuthErrorResponse>>Handler function for App Router

Usage

src/pages/api/auth/login.ts
import { createLoginHandler } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

export default createLoginHandler(authConfig);

Request

The login handler expects a POST request with a JSON body containing the following fields:

FieldDescriptionTypeRequired
emailUser emailstring
nextPageRedirect pathnamestring | null
passwordUser passwordstring

Response

The success response body is a JSON object with the following fields:

FieldDescriptionType
data.redirectUrlThe URL to redirect the user to after login.string | null

The error response body is a JSON object with the following fields:

FieldDescriptionType
error.errorCodeError codeErrorCode
error.messageError messagestring
error.sourceSource of the error"blueprint-auth"
Status Codes
Status CodeCondition
200 OKSuccessful login with redirect URL in response body (when enableRedirect is false)
307 Temporary RedirectSuccessful login, redirect to dashboard or nextPage (when enableRedirect is true)
400 Bad RequestInvalid request body, invalid email format, missing required fields (email/password), authentication failed, or any validation error
405 Method Not AllowedRequest method is not POST

createLogoutHandler

The logout handler removes auth cookies and provides a redirect URL in the response.

Configuration

OptionDescriptionTypeRequired
i18n.localeCookieName of the cookie storing user's locale preferencestring
i18n.getLocalizedPathnameCallback to resolve localized pathnames(options: GetLocalizedPathnameOptions) => string | Promise<string>

Output

TypeDescription
(req: NextApiRequest, res: NextApiResponse) => Promise<void>Handler function for Pages Router
(req: NextRequest) => Promise<NextResponse<unknown | AuthErrorResponse>>Handler function for App Router

Usage

src/pages/api/auth/logout.ts
import { createLogoutHandler } from "@krakentech/blueprint-auth/server";

export default createLogoutHandler();

Request

The logout handler expects a POST request with a JSON body containing the following fields:

FieldDescriptionTypeRequired
nextPageRedirect pathnamestring | null

Response

The success response body is a JSON object with the following fields:

FieldDescriptionType
data.redirectUrlThe URL to redirect the user to after login.string | null

The error response body is a JSON object with the following fields:

FieldDescriptionType
error.errorCodeError codeErrorCode
error.messageError messagestring
error.sourceSource of the error"blueprint-auth"
Status Codes
Status CodeCondition
200 OKSuccessful logout with redirect URL in response body (when enableRedirect is false)
307 Temporary RedirectSuccessful logout, redirect to home or nextPage (when enableRedirect is true)
400 Bad RequestInvalid request body (validation error)
405 Method Not AllowedRequest method is not POST
500 Internal Server ErrorUnknown logout operation error

createSessionHandler

The session handler reads auth cookies and provides the current session data.

Configuration

No configuration needed.

Output

TypeDescription
(req: NextApiRequest, res: NextApiResponse) => Promise<void>Handler function for Pages Router
(req: NextRequest) => Promise<NextResponse<AuthSuccessResponse<SessionState> | AuthErrorResponse>>Handler function for App Router

Usage

src/pages/api/auth/session.ts
import { createSessionHandler } from "@krakentech/blueprint-auth/server";

export default createSessionHandler();

Request

The session handler expects a GET request.

Response

The success response body is a JSON object with the following fields:

FieldDescriptionType
data.isAuthenticatedUser has an auth token cookieboolean
data.authMethodActive auth methodAuthMethod
data.subThe value of the sub cookie if setstring | null

The error response body is a JSON object with the following fields:

FieldDescriptionType
error.errorCodeError codeErrorCode
error.messageError messagestring
error.sourceSource of the error"blueprint-auth"
Status Codes
Status CodeCondition
200 OKSuccessfully retrieved session state
405 Method Not AllowedRequest method is not GET
500 Internal Server ErrorFailed to read session details (any error)

createGraphQLHandler

The GraphQL handler proxies requests to the GraphQL endpoint specified by krakenConfig.graphqlEndpoint after setting the Authorization header depending on the incoming request cookies.

Configuration

OptionDescriptionTypeEnvironment variableRequired
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstringKRAKEN_GRAPHQL_AUTH_ENDPOINT
krakenConfig.graphqlEndpointTarget GraphQL endpointstringKRAKEN_GRAPHQL_ENDPOINT
krakenConfig.xClientIpOverrideOverride for the user IP header (for tests)string
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstringKRAKEN_X_CLIENT_IP_SECRET_KEY

Output

TypeDescription
(req: NextApiRequest, res: NextApiResponse) => Promise<void>Handler function for Pages Router
(req: NextRequest) => Promise<NextResponse<unknown>>Handler function for App Router

Usage

src/pages/api/graphql/kraken.ts
import { createGraphQLHandler } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

export default createGraphQLHandler(authConfig);

Request

The GraphQL handler expects a POST request with a JSON body containing the following fields:

FieldDescriptionTypeRequired
queryGraphQL query/mutationstring
variablesVariables of the GraphQL query/mutationobject

Optional request header: the handler accepts the x-error-policy header to set the error policy for that request (e.g. when the client is created with useGraphQLClient({ errorPolicy: "…" })). Values are case-sensitive: "none", "ignore", "all".

Response

The success response body is a JSON object with the following fields:

FieldDescriptionType
dataResponse of GraphQL query/mutationobject the shape depends on the query/mutation

The error response body is a JSON object with the following fields:

FieldDescriptionType
dataResult of the query/mutationobject | null the shape depends on the query/mutation
errorsGraphQL errorsKrakenError[]
Automatic token refresh

If the accessToken cookie expired, the GraphQL handler attempts to refresh it using the refreshToken cookie.

Error handling

The GraphQL handler passes errors returned by the GraphQL API endpoint through.

In case an error occurs inside of the GraphQL handler, the error is converted to match the KrakenError interface, and includes the following fields:

FieldDescriptionType
messageError messagestring
extensions.errorCodeError codestring
extensions.errorDescriptionError descriptionstring
Status Codes
Status CodeCondition
200 OKSuccessful GraphQL request or GraphQL request with errors (errors returned in response body)
400 Bad RequestInvalid request body, missing query field, or invalid query/variables
401 UnauthorizedKraken API returns UNAUTHORIZED error code
405 Method Not AllowedRequest method is not POST
500 Internal Server ErrorUnknown GraphQL operation error

createKrakenOAuthHandler

The Kraken OAuth handler authenticates the user using the Kraken OAuth flow. It is meant to be used in combination with generateKrakenOAuthURI. It fetches auth tokens from Kraken, sets auth cookies, and redirects the user to the dashboard page on success. In case authentication fails, the user is redirected to the login page with the error code as the error URL search parameter.

Configuration

OptionDescriptionTypeEnvironment variableRequired
krakenConfig.authEndpointKraken auth endpointstringKRAKEN_AUTH_ENDPOINT
krakenConfig.oauthClientIdKraken OAuth client IDstringKRAKEN_OAUTH_CLIENT_ID

Output

TypeDescription
(req: NextApiRequest, res: NextApiResponse) => Promise<void>Handler function for Pages Router
(req: NextRequest) => Promise<NextResponse<unknown | AuthErrorResponse>>Handler function for App Router

Usage

src/pages/api/auth/oauth/kraken.ts
import { createKrakenOAuthHandler } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

export default createKrakenOAuthHandler(authConfig);

Request

The Kraken OAuth handler expects a GET request with the following URL search parameters:

URL search parameterDescriptionTypeRequired
codeKraken OAuth codestring
PKCE Verifier

The Kraken OAuth handler requires a Proof Key for Code Exchange (PKCE) stored as the pkce-verifier cookie on the incoming request. This cookie is set by the handler of the URL returned by generateKrakenOAuthURI.

Response

The Kraken OAuth handler responds with a redirect response. The Location header is set to the dashboard page on success, and to the login page with error code on failure.

Status Codes
Status CodeCondition
307 Temporary Redirect (to Dashboard)Successful OAuth authentication
307 Temporary Redirect (to Login)error query parameter present in callback, missing or invalid code query parameter, missing code_verifier cookie, OAuth token exchange failed, invalid token validation (iss/aud/sub), or any authentication error
405 Method Not AllowedRequest method is not GET

createUpdateOrgTokenHandler

The organization token update handler is meant to be used as a Vercel cron job. It fetches a new organization token and stores the value in the Edge Config store.

Configuration

OptionDescriptionTypeEnvironment variableRequired
krakenConfig.graphqlAuthEndpointGraphQL endpoint for auth operationsstringKRAKEN_GRAPHQL_AUTH_ENDPOINT
krakenConfig.organizationSecretKeyKraken organization secret keystringKRAKEN_ORGANIZATION_KEY
krakenConfig.xClientIpSecretKeySecret key to sign the user IP addressstringKRAKEN_X_CLIENT_IP_SECRET_KEY
Vercel Secured cron job

The organization token update handler requires the CRON_SECRET environment variable to be set. This ensures the handler can only be called as a cron job.

Vercel automatically sets the CRON_SECRET environment variable as the Authorization header in cron jobs. The handler responds with a 401 Unauthorized status response in case the header and the environment variable do not match.

Check out the Vercel documentation to learn more.

Output

TypeDescription
(req: NextApiRequest, res: NextApiResponse) => Promise<void>Handler function for Pages Router
(req: NextRequest) => Promise<NextResponse<unknown>>Handler function for App Router

Usage

src/pages/api/auth/update-org-token.ts
import { createUpdateOrgTokenHandler } from "@krakentech/blueprint-auth/server";
import { authConfig } from "@/lib/auth/config";

export default createUpdateOrgTokenHandler(authConfig);

To setup the cron job, create a vercel.json at the root of your project with the following content:

vercel.json
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"crons": [
{
"path": "/api/auth/update-org-token",
"schedule": "*/55 * * * *"
}
]
}
cron job configuration

The organization token lifetime is usually set to 1 hour. The example above run the cron job every 55 minutes, but you can customize the schedule field to better fit your needs. Check out Vercel's cron expressions guide.

Request

The update organization token handler expects a GET request with the Authorization header set to Bearer {CRON_SECRET}.

Response

The handler returns an empty response body.

Status Codes
Status CodeCondition
200 OKSuccessfully updated organization token
401 UnauthorizedMissing Authorization header or header doesn't match CRON_SECRET
405 Method Not AllowedRequest method is not GET
500 Internal Server ErrorError updating organization token, Edge config write failure, or any unknown error

Client Functions

App Router

If you are using the Next.js App Router, you most likely do not need any of these helpers, use Server Functions instead.

createClientSideAuth

Creates AuthProvider and the hooks depending on it, i.e. useAuth, useGraphQLClient, useKrakenAuthErrorHandler, useLogin, useLogout, and useSession.

Configuration

OptionDescriptionTypeRequired
appRoutes.dashboard.pathnameDashboard pathnamestring
appRoutes.login.pathnameLogin pathnamestring

Parameters

ParamDescriptionTypeRequired
defaultTargetDefault GraphQL API endpointkeyof typeof apiRoutes.graphql
routerSpecifies which Next.js router the application uses."app-router" | "pages-router"
Multiple GraphQL endpoints

If your application uses multiple GraphQL endpoints relying on Kraken authentication, you can define them in the apiRoutes.graphql object.

{
apiRoutes: {
graphql: {
kraken: "/api/graphql/kraken",
custom: "/api/graphql/custom",
}
}
}
Default GraphQL target

The createClientSideAuth factory expects an options object as its second argument with two properties:

  • defaultTarget: The default GraphQL endpoint used by useGraphQLClient. The value must be a key of the apiRoutes.graphql object.
  • router: The Next.js router being used. Must be either "pages-router" or "app-router".

Usage

Export the functions returned by createClientSideAuth.

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

export const {
AuthProvider,
useAuth,
useGraphQLClient,
useKrakenAuthErrorHandler,
useLogin,
useLogout,
useSession,
} = createClientSideAuth(authConfig, {
defaultTarget: "kraken",
router: "pages-router",
});

AuthProvider

Provides configuration to auth hooks.

Configuration

OptionDescriptionTypeRequired
onLoginSuccessSuccessful login callback(defaultRedirect: () => void) => void | Promise<void>
onLoginErrorLogin error callback(errorCode: [ErrorCode](#errorcode), defaultRedirect: () => void) => void | Promise<void>
onLogoutSuccessSuccessful logout callback(defaultRedirect: () => void) => void | Promise<void>
onLogoutErrorLogout error callback(errorCode: [ErrorCode](#errorcode), defaultRedirect: () => void) => void | Promise<void>
Extend the default redirect behavior

Providing handlers overrides the default redirect behavior of the useLogin and useLogout hooks. In case you need to extend the default behavior, all callbacks are called with the defaultRedirect function.

Usage

In your Next.js _app.tsx file, wrap the page component with AuthProvider, and optionally define custom handlers.

pages/_app.tsx
import { useRouter } from "next/router";
import { useToast } from "@/hooks/useToast";
import { authConfig } from "@/lib/auth/config";
import { AuthProvider } from "@/lib/auth/client";

export default function App({ Component, pageProps }) {
const router = useRouter();
const toast = useToast("auth");
return (
<AuthProvider
// extend default behavior
onLoginSuccess={(defaultRedirect) => {
defaultRedirect();
toast("login.success", { type: "success" });
}}
// override default behavior
onLoginError={(errorCode) => {
toast("login.error", { errorCode, type: "error" });
}}
// optionally extend default behavior
onLogoutSuccess={(defaultRedirect) => {
toast("logout.success", { type: "success" });
if (router.pathname.startsWith("/dashboard")) {
defaultRedirect();
}
}}
>
<Component {...pageProps} />
</AuthProvider>
);
}

useAuth

This hook is used internally by other auth hooks to access the AuthProviderContext state.

Advanced use cases

This hook is exposed for convenience in advanced use cases, e.g. custom auth hooks. In most cases you should not use it directly.

Configuration

No configuration needed.

Output

FieldDescriptionTypeRequired
apiRoutes.graphqlGraphQL API endpointsRecord<string, string>
apiRoutes.loginLogin API endpointstring
apiRoutes.logoutLogout API endpointstring
apiRoutes.sessionSession API endpointstring
appRoutes.dashboard.pathnameDashboard pathnamestring
appRoutes.login.pathnameLogin pathnamestring
defaultTargetDefault GraphQL endpointstring
handlers.onLoginSuccessSuccessful login callback(defaultRedirect: () => void) => void | Promise<void>
handlers.onLoginErrorLogin error callback(errorCode: AuthErrorCode, defaultRedirect: () => void) => void | Promise<void>
handlers.onLogoutSuccessSuccessful logout callback(defaultRedirect: () => void) => void | Promise<void>
handlers.onLogoutErrorLogout error callback(errorCode: AuthErrorCode, defaultRedirect: () => void) => void | Promise<void>

Requirements

RequirementNotes
Context providerUse inside AuthProvider.
Client-side authThe component must be wrapped with a client-side auth setup using createClientSideAuth.

Usage

hooks/useCustomLogin.ts
import { useAuth } from "@/lib/auth/client";

function useCustomLogin() {
const { apiRoutes, appRoutes, defaultTarget, handlers } = useAuth();
...
}

useGraphQLClient

Get a preconfigured GraphQL client to perform authenticated requests to the Kraken GraphQL API endpoint, or GraphQL API endpoint relying on Kraken for authentication.

Requirements

RequirementNotes
API endpointCreate the GraphQL API endpoint at apiRoutes.graphql using createGraphQLHandler.
Context providerUse inside AuthProvider.

Configuration

ParameterDescriptionTypeRequired
targetTarget GraphQL endpoint (must be a key of the apiRoutes.graphql object provided to createClientSideAuth)string❌ Defaults to the default target
errorPolicyHow the client handles GraphQL errors: "none" (default), "ignore", or "all". See Error policy."none" | "ignore" | "all"❌ Defaults to "none"

Output

FieldDescriptionTypeRequired
graphQLClientGraphQL client instanceGraphQLClient

Usage

hooks/useAccount.ts
import { useQuery } from "@tanstack/react-query";
import { AccountQuery } from "@/graphql/AccountQuery";
import { useGraphQLClient } from "@/lib/auth/client";

export function useAccount(variables: { accountNumber: string }) {
// using the default target and error policy (no args needed)
const { graphQLClient } = useGraphQLClient();
// using a different target:
const { graphQLClient } = useGraphQLClient({ target: "custom" });
// with a custom error policy:
const { graphQLClient } = useGraphQLClient({ errorPolicy: "ignore" });

return useQuery({
queryKey: ["account", variables.accountNumber],
queryFn: () => graphQLClient.request(AccountQuery, variables),
});
}
GraphQL Client

The returned client is a GraphQLClient instance from the graphql-request library. It provides a request method with the same signature as AuthenticatedGraphQLClient, plus additional methods like batchRequests.

useKrakenAuthErrorHandler

The hook provides an error handler to be used with data fetching libraries. If the error is auth-related the handler redirects the user to the login page with error and nextPage search parameters.

Requirements

RequirementNotes
Context providerUse inside AuthProvider.

Configuration

OptionDescriptionTypeRequired
onErrorError callback(error: unknown, defaultRedirect: () => void) => void | Promise<void>
redirectTypeRedirect type"push" | "replace"❌ Defaults to "push"
Extend the default redirect behavior

Providing onError overrides the default redirect behavior of the useKrakenAuthErrorHandler hook. In case you need to extend the default behavior, the onError callback is called with the defaultRedirect function.

Output

FieldDescriptionTypeRequired
handleKrakenErrorsError handler(error: unknown) => void | Promise<void>
i18n Support

When i18n is configured, this hook redirects to localized login pages based on the user's locale.

Usage

hooks/useAccount.ts
import { useQuery } from "@tanstack/react-query";
import { AccountQuery } from "@/graphql/AccountQuery";
import { useGraphQLClient, useKrakenAuthErrorHandler } from "@/lib/auth/client";

export function useAccount(variables: { accountNumber: string }) {
const { graphQLClient } = useGraphQLClient();
const { handleKrakenErrors } = useKrakenAuthErrorHandler();
return useQuery({
queryKey: ["account", variables.accountNumber],
queryFn: () => graphQLClient.request(AccountQuery, variables),
onError: handleKrakenErrors,
});
}

useLogin

The useLogin hook can be used to authenticate the user, and handles redirection for both success and failure cases.

Learn more about the useLogin hook redirect behavior

Default success redirect

  1. Redirect to the nextPage option if set.
  2. Redirect to the nextPage URL search parameter if set.
  3. Redirect to the appRoutes.dashboard.pathname otherwise.

Default failure redirect

Set the error URL search parameter in the current URL.

Customizing redirects

To customize the redirects, you can provide the onLoginSuccess and onLoginError callbacks to AuthProvider, or pass additional onSuccess and onError callbacks to login.mutate or login.mutateAsync.

Redirect callback behavior

If the handlers.onLoginSuccess callback set on the AuthProvider does not call the defaultRedirect function, the nextPage option and the nextPage URL search parameter have no effect.

Requirements

RequirementNotes
API endpointCreate the login API endpoint at apiRoutes.login using createLoginHandler.
Context providerUse inside AuthProvider.
React QueryUse inside of <QueryClientProvider>, see the Pages Router or the App Router example.
Login API Handler

The useLogin hook expects the login API handler created with createLoginHandler to be available on the apiRoutes.login endpoint.

QueryClientProvider

The useLogin hook uses React Query's useMutation under the hood. It must be used inside of <QueryClientProvider>. Check out React Query's Pages Router example. or App Router example.

Configuration

OptionDescriptionTypeRequired
nextPageRedirect pathnamestring | null

Output

Returns a UseMutationResult object, see React Query's useMutation hook documentation.

Usage

components/LoginForm.tsx
import { useLogin } from "@/lib/auth/client";

export function LoginForm(props: LoginFormProps) {
const login = useLogin();

function handleSubmit() {
// trigger the login mutation
login.mutate({ email: "example@email.com", password: "****" });
}

async function handleSubmit() {
// alternatively, you can use the async version
await login.mutateAsync({ email: "example@email.com", password: "****" });
}
}
Display errors

The error code can be read from the error URL search parameter. The UseMutationResult object returned by the useLogin hook also includes the error response accessible as login.error. The error code can be extracted from the error response using the getErrorCode utility function.

Progressive enhancements

The useLogin hook can be used to create a login form that works even before the page is fully hydrated, or if JavaScript is disabled. Check out our Building Forms guide to learn more.

useLogout

The useLogout hook can be used to log out the user, and handles redirection for both success and failure cases.

Learn more about the useLogout hook redirect behavior

Default success redirect

  1. Redirect to the nextPage option if set.
  2. Redirect to the / otherwise.

Default failure redirect

Set the error URL search parameter in the current URL.

Customizing redirects

To customize the redirects, you can provide the onLogoutSuccess and onLogoutError callbacks to AuthProvider, or pass additional onSuccess and onError callbacks to logout.mutate or logout.mutateAsync.

Redirect callback behavior

If the handlers.onLogoutSuccess callback set on the AuthProvider does not call the defaultRedirect function, the nextPage option has no effect.

Requirements

RequirementNotes
API endpointCreate the logout API endpoint at apiRoutes.logout using createLogoutHandler.
Context providerUse inside AuthProvider.
React QueryUse inside of <QueryClientProvider>, see the Pages Router or the App Router example.
Logout API Handler

The useLogout hook expects the logout API handler created with createLogoutHandler to be available on the apiRoutes.logout endpoint.

QueryClientProvider

The useLogout hook uses React Query's useMutation under the hood. It must be used inside of <QueryClientProvider>. Check out React Query's Pages Router example. or App Router example.

Configuration

OptionDescriptionTypeRequired
nextPageRedirect pathnamestring | null

Output

TypeDescription
UseMutationResultReact Query mutation result, see useMutation docs

Usage

components/LogoutButton.tsx
import { useLogout } from "@/lib/auth/client";

export function LogoutButton() {
const logout = useLogout();

function handleClick() {
// trigger the logout mutation
logout.mutate();
}

async function handleClick() {
// alternatively, you can use the async version
await logout.mutateAsync();
}

return (
<button type="button" onClick={handleClick}>
Logout
</button>
);
}
Display errors

The error code can be read from the error URL search parameter. The UseMutationResult object returned by the useLogout hook also includes the error response accessible as logout.error. The error code can be extracted from the error response using the getErrorCode utility function.

Progressive enhancement

The useLogout hook can be used to create a logout button that works even before the page is hydrated, or if JavaScript is disabled. Check out our Building Forms tutorial to learn more.

useSession

The useSession hook can be used to access information about the current user session.

Requirements

RequirementNotes
API endpointCreate the session API endpoint at apiRoutes.session using createSessionHandler.
Context providerUse inside AuthProvider.
React QueryUse inside of <QueryClientProvider>, see the Pages Router or the App Router example.

Configuration

No configuration needed.

Output

Returns a DefinedUseQueryResult<SessionState, unknown> object.

The SessionState data includes:

FieldDescriptionType
authMethodThe active authentication method based on cookie priorityAuthMethod | null
isAuthenticatedUser has an auth token cookieboolean
subThe value of the sub cookie if setstring | null
Example usage
const { data: session } = useSession();

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

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

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

redirectToNextPage

The redirectToNextPage function redirects the user to the relative URL found in the nextPage URL search parameter.

Fallback behavior

If nextPage is empty or contains an absolute URL, the fallback is used. If nextPage is invalid and the fallback is not provided, the function has no effect.

Requirements

RequirementNotes
Pages RouterThis function relies expects a NextRouter instance, which can only be used with the Pages Router.

Configuration

OptionDescriptionTypeRequired
routerThe NextRouter instanceNextRouter
fallbackThe fallback URL in case nextPage is empty or invalidstring
redirectTypeThe type of navigationpush | replace❌ defaults to replace

Usage

import { useRouter } from "next/router";
import { redirectToNextPage } from "@krakentech/blueprint-auth/client";

const Page = () => {
const router = useRouter();

useEffect(() => {
redirectToNextPage({
router,
fallback: "/dashboard",
});
}, []);

return <p>Redirecting...</p>;
};

Utils

convertIterableToRecord

Converts an Iterable (like an Iterator or generator) to a Record object.

function convertIterableToRecord<
T extends {
entries(): Iterable<readonly [string, string]>;
},
>(iterable: T): Record<string, string | string[]>;

Configuration

ParameterDescriptionTypeRequired
iterableThe iterable to convertT extends { entries(): Iterable<readonly [string, string]>}

Output

TypeDescription
Record<string, string | string[]>A record object created from the iterable

Usage

const iterable = Map([
["key1", "value1"],
["key2", "value2"],
]);
const record = convertIterableToRecord(iterable);
// { key1: "value1", key2: "value2" }

convertRecordToIterable

Converts a Record object back to an Iterable.

function convertRecordToIterable<
Entry,
Target extends { append(key: string, value: string): void },
>(record: Record<string, Entry>, target: Target): Target;

Configuration

ParameterDescriptionTypeRequired
recordThe record to convertRecord<string, Entry>
targetThe target iterable to append toTarget extends { append(key: string, value: string): void }

Output

TypeDescription
TargetThe target iterable with appended entries

Usage

const record = { key1: "value1", key2: "value2" };
const iterable = convertRecordToIterable(record);
// Map(2) { "key1" => "value1", "key2" => "value2" }

getErrorCode

Get the error code from a client-side function or from a GraphQL operation.

Configuration

Expect an error of type unknown.

Output

TypeCondition
BlueprintAuthErrorCodeBlueprint auth error
MappedKrakenErrorCodeMapped Kraken error
nullNo error code found

Usage

queries/getAccount.ts
import { getUserScopedGraphQLClient } from "@krakentech/blueprint-auth/server";
import { reportGraphQLError } from "@/lib/error/reporting";

async function getAccount(variables: { accountNumber: string }) {
try {
const graphQLClient = getUserScopedGraphQLClient();
const { account } = await graphQLClient.request(AccountQuery, variables);
return account;
} catch (error) {
const errorCode = getErrorCode(error);
if (errorCode) {
return reportGraphQLError(error, { errorCode });
}
return reportUnexpectedError(error);
}
}

isBlueprintAuthErrorCode

Check if an error code is a valid BlueprintAuthErrorCode.

Configuration

Expect an error code of type string.

Output

TypeDescription
booleanTrue if valid Blueprint auth error

Usage

utils/getErrorMessage.ts
import { getTranslations } from "next-intl/server";
import { isBlueprintAuthErrorCode } from "@krakentech/blueprint-auth/utils";
import { isMappedKrakenErrorCode } from "@krakentech/blueprint-api/utils";

async function getErrorMessage(error: unknown) {
const t = await getTranslations("getErrorMessage");
const errorCode = getErrorCode(error);
if (errorCode) {
if (isBlueprintAuthErrorCode(errorCode)) {
return t(`blueprint-auth.${errorCode}`);
}
if (isMappedKrakenErrorCode(errorCode)) {
return t(`kraken.${errorCode}`);
}
}
return t("unknown");
}

setNextPageSearchParam

This function sets the nextPage URL search parameter. This is the URL search parameter that we are setting in the authMiddleware function when we redirect the user to the login page.

Configuration

OptionDescriptionTypeRequired
nextPageRedirect page pathname or URLstring | URL | NextUrl
urlThe URL on which the nextPage URL search parameter should be setURL | NextUrl

Output

Returns void.

Usage

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

const url = new URL("https://example.com/login");
setNextPageSearchParam({
nextPage: "/profile/settings?tab=update-password",
url,
});
// url.href → https://example.com/login?nextPage=%2Fprofile%2Fsettings%3Ftab%3Dupdate-password
Search parameters

If the nextPage URL includes search parameters, they are included in the encoded nextPage URL search parameter along with the URL pathname.

Automatic removal of auth parameters

The setNextPageSearchParam automatically removes the nextPage and error URL search parameters from the nextPage URL if they are set.

setKrakenAuthTokenOverrideHeader

Manually set the Kraken auth token override header.

Configuration

OptionDescriptionTypeRequired
headersHeaders objectHeaders
tokenOverride token valuestring

Output

TypeDescription
voidNo return value

Usage

app/subscribe/checkout/action.ts
"use server";

import { setKrakenAuthTokenOverrideHeader } from "@krakentech/blueprint-auth/utils";
import { headers } from "next/headers";
import { redirect } from "next/navigation";
import { getUserScopedGraphQLClient } from "@/lib/auth/server";
import { CheckoutQuoteInput, CheckoutQuote } from "@/mutations/checkout-quote";
import {
handleRequestError,
handleSubmissionError,
parseSubmission,
type FormState,
} from "@/utils/form-actions";

export async function checkoutAction(
token: string,
_formState: FormState,
formData: FormData,
) {
const submission = parseSubmission(formData, CheckoutQuoteInput);
if (!submission.success) {
return handleSubmissionError(submission);
}

const requestHeaders = new Headers(await headers());
setKrakenAuthTokenOverrideHeader(requestHeaders, token);

try {
const graphQLClient = getUserScopedGraphQLClient();
await graphQLClient.request(CheckoutQuote, submission.data, requestHeaders);
} catch (error) {
return handleRequestError(error, submission);
}

redirect("/subscribe/confirmation");
}

Classes

AuthenticatedGraphQLClient

The AuthenticatedGraphQLClient class provides a GraphQL client with automatic authentication, token refresh, and intelligent retry logic. It is returned by getUserScopedGraphQLClient and getOrganizationScopedGraphQLClient.

Error policy

The client supports an optional error policy that controls how GraphQL errors in responses are handled:

PolicyBehavior
"none"(default) GraphQL errors cause the request to throw.
"ignore"GraphQL errors are ignored; response data is returned even when the response contains errors.
"all"Response includes both data and errors (rawRequest-style), so the caller can handle errors explicitly.

You can set the error policy when creating the client (e.g. via getUserScopedGraphQLClient({ context, errorPolicy: "ignore" }) or getOrganizationScopedGraphQLClient({ errorPolicy: "ignore" })). You can also override it per request by passing the xErrorPolicyHeader in requestHeaders:

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

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

const result = await graphQLClient.request({
document: MyQuery,
requestHeaders: { [xErrorPolicyHeader]: "ignore" },
});

request<T, V>(document, variables?, headers?): Promise<T>

Execute a GraphQL query or mutation with automatic authentication.

Parameters

Pass up to three separate arguments to the request method.

ParameterTypeDescriptionRequired
documentRequestDocument | TypedDocumentNodeGraphQL query/mutation document
variablesVGraphQL variables
requestHeadersHeadersInitRequest-level headers
const { account } = await graphQLClient.request(
AccountQuery,
{ accountNumber: "A-12345678" },
{ "x-custom-header": "my-value" },
);
Output
TypeDescription
Promise<T>The GraphQL response data
Throws
Error TypeCondition
AuthError (BlueprintAuthErrorCode.TokenAccessInvalid)Token refresh fails after 3 retries (rare - automatic retry usually succeeds)
AuthError (BlueprintAuthErrorCode.Forbidden)Mutation attempted when preventGraphQLMutations is enabled
Kraken API errorsGraphQL operation failures (validation, permissions, etc.)
Usage

Execute GraphQL queries and mutations with automatic authentication:

import { getUserScopedGraphQLClient } from "@/lib/auth/server";
import { graphql } from "@/gql-tada";

const AccountQuery = graphql(`
query Account($accountNumber: String!) {
account(accountNumber: $accountNumber) {
number
balance
status
}
}
`);

export async function getServerSideProps(context) {
const graphQLClient = getUserScopedGraphQLClient({ context });

const { account } = await graphQLClient.request(AccountQuery, {
accountNumber: "A-12345678",
});

return {
props: { account },
};
}

Retry Behavior

When a GraphQL request fails due to an invalid or expired token, the client automatically:

  1. Marks the current token as invalid
  2. Requests a new token via the configured getNewAuthToken callback
  3. Retries the original request with the new token
  4. Repeats up to 3 times before throwing an error

This ensures seamless operation even when tokens expire during request execution.


AuthError

Custom error class for authentication operations. All errors thrown by @krakentech/blueprint-auth functions are instances of AuthError.

Constructor

new AuthError(message: string, options?: { code?: ErrorCode; cause?: unknown })

Parameters:

ParameterTypeDescriptionRequired
messagestringHuman-readable error message
options.codeErrorCodeError code (Blueprint or Kraken)
options.causeunknownUnderlying error that caused this error

Properties

PropertyTypeDescription
messagestringHuman-readable error message
codeErrorCodeError code identifying the type of error
causeunknownOriginal error that caused this error (if any)
namestringAlways "AuthError"

Usage

import { AuthError, BlueprintAuthErrorCode } from "@krakentech/blueprint-auth";

// throwing an AuthError
throw new AuthError("Invalid credentials", {
code: BlueprintAuthErrorCode.BadRequest,
});

// catching and handling AuthError
try {
await login({ context, input: { email, password } });
} catch (error) {
if (error instanceof AuthError) {
console.error("Auth error:", error.code, error.message);

if (error.code === BlueprintAuthErrorCode.TokenAccessInvalid) {
// handle expired token
}
}
}

Error Code Utilities

Use these utility functions to work with AuthError instances:


Types

AuthMethod

Represents the authentication method currently in use.

type AuthMethod =
| "email"
| "oauth"
| "scoped"
| "masquerade"
| "mobile-web-view"
| (string & {}); // Allows autocomplete while accepting unknown strings

Values

ValueDescriptionPriority
"masquerade"Staff impersonation via masquerade tokenHighest
"mobile-web-view"Mobile app integration via MWAuthTokenHigh
"oauth"OAuth-based authenticationMedium
"email"Email/password authenticationMedium
"scoped"Anonymous/pre-signed key access via scoped tokenLowest
nullNo authentication presentN/A

Priority

In case multiple authentication cookies are present, the AuthMethod is determined by priority order (highest to lowest):

  1. masquerade - Takes precedence over all other authentication methods
  2. mobile-web-view - Takes precedence over standard login and scoped sessions
  3. oauth or email - Standard authenticated sessions (determined by authProvider cookie)
  4. scoped - Anonymous/pre-signed key access

This priority system ensures that masquerade and mobile app integration always take precedence, preventing lower-priority authentication from overriding higher-priority sessions.

Usage

The AuthMethod type is available in the SessionState object returned by getSession() and useSession():

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 />
}

SessionState

Represents the current user session state. See getSession and useSession for full documentation.

type SessionState = {
authMethod: AuthMethod | null;
isAuthenticated: boolean;
sub: string | null;
};

AuthScope

Represents the scope of authentication for GraphQL operations.

type AuthScope = "user" | "organization";

Values

ValueDescription
"user"User-scoped authentication - operations performed on behalf of a user
"organization"Organization-scoped authentication - operations performed with org-level credentials

Usage

The AuthScope type is used in the customization.setCustomHeaders callback and internally by GraphQL client functions.

const authConfig = createAuthConfig({
customization: {
setCustomHeaders(headers, authScope) {
if (authScope === "organization") {
headers.set("X-Custom-Org-Header", "value");
}
},
},
});

CookieName

Valid authentication cookie names used throughout the package.

type CookieName =
| "accessToken"
| "authProvider"
| "masqueradeToken"
| "MWAuthToken"
| "MWRefreshToken"
| "pkce-verifier"
| "refreshToken"
| "scopedToken"
| "sub";

Usage

This type is used by createAuthCookieUtils functions to ensure type-safe cookie operations. See the AUTH_COOKIE constant for the actual cookie name values.

const { setAuthCookie } = createAuthCookieUtils({ context });

await setAuthCookie({
name: "accessToken", // type-safe: must be a valid CookieName
value: token,
expires: new Date(Date.now() + 3600000),
});

CookieMap

A Map containing authentication cookie names and their values.

type CookieMap = Map<CookieName, string | undefined>;

Usage

Returned by getAuthCookies() and used by getActiveAuthMethod() and getCookieMapItem() for type-safe cookie operations. See CookieName for valid cookie name values.

const { getAuthCookies, getActiveAuthMethod, getCookieMapItem } =
createAuthCookieUtils({ context });

const cookies = await getAuthCookies(); // Returns CookieMap
const authMethod = getActiveAuthMethod(cookies);

// get specific cookie from the map
const accessToken = getCookieMapItem({
cookies,
name: "accessToken",
});

BlueprintAuthErrorCode

Blueprint-specific error codes for authentication operations. All error codes follow the pattern BP-AUTH-XXXX.

const BlueprintAuthErrorCode = {
/* General Errors */
Unknown: "BP-AUTH-0000",
BadRequest: "BP-AUTH-0001",
ResponseNotFound: "BP-AUTH-0003",
Forbidden: "BP-AUTH-0004",
/* Token Errors */
TokenUnknown: "BP-AUTH-0100",
TokenAccessInvalid: "BP-AUTH-0101",
TokenNotRefreshable: "BP-AUTH-0102",
/* API Handler Errors */
ApiHandlerUnknown: "BP-AUTH-0200",
ApiHandlerRequestNotFound: "BP-AUTH-0201",
ApiHandlerInvalidParameters: "BP-AUTH-0202",
ApiHandlerMethodNotAllowed: "BP-AUTH-0203",
/* Server Function Errors */
ServerFunctionUnknown: "BP-AUTH-0300",
ServerFunctionUnsupportedExecutionContext: "BP-AUTH-0301",
/* Operation Errors */
OperationUnknown: "BP-AUTH-0400",
OperationLoginUnknown: "BP-AUTH-0410",
OperationOAuthUnknown: "BP-AUTH-0420",
OperationLogoutUnknown: "BP-AUTH-0430",
OperationSessionUnknown: "BP-AUTH-0440",
OperationGraphQLUnknown: "BP-AUTH-0450",
/* Edge Config Errors */
EdgeConfigUnknown: "BP-AUTH-0500",
EdgeConfigFetch: "BP-AUTH-0501",
EdgeConfigFetchUpdated: "BP-AUTH-0502",
EdgeConfigUpdate: "BP-AUTH-0503",
/* Encryption Errors */
EncryptionUnknown: "BP-AUTH-0600",
/* Validation Errors */
ValidationUnknown: "BP-AUTH-0700",
ValidationApiUrl: "BP-AUTH-0701",
ValidationMissingProperties: "BP-AUTH-0702",
ValidationInvalidProperties: "BP-AUTH-0703",
/* Client Errors */
ClientUnknown: "BP-AUTH-0800",
ClientHookUsedOutsideOfProvider: "BP-AUTH-0802",
} as const;

type BlueprintAuthErrorCode =
(typeof BlueprintAuthErrorCode)[keyof typeof BlueprintAuthErrorCode];

Error Codes

CodeConstantCategoryDescription
BP-AUTH-0000UnknownGeneralUnknown error
BP-AUTH-0001BadRequestGeneralBad request
BP-AUTH-0003ResponseNotFoundGeneralResponse not found
BP-AUTH-0004ForbiddenGeneralForbidden operation
BP-AUTH-0100TokenUnknownTokenUnknown token error
BP-AUTH-0101TokenAccessInvalidTokenInvalid or expired access token
BP-AUTH-0102TokenNotRefreshableTokenToken cannot be refreshed
BP-AUTH-0200ApiHandlerUnknownAPI HandlerUnknown API handler error
BP-AUTH-0201ApiHandlerRequestNotFoundAPI HandlerAPI request not found
BP-AUTH-0202ApiHandlerInvalidParametersAPI HandlerInvalid parameters provided to API handler
BP-AUTH-0203ApiHandlerMethodNotAllowedAPI HandlerHTTP method not allowed
BP-AUTH-0300ServerFunctionUnknownServer FunctionUnknown server function error
BP-AUTH-0301ServerFunctionUnsupportedExecutionContextServer FunctionServer function called in unsupported context
BP-AUTH-0400OperationUnknownOperationUnknown operation error
BP-AUTH-0410OperationLoginUnknownOperationUnknown login operation error
BP-AUTH-0420OperationOAuthUnknownOperationUnknown OAuth operation error
BP-AUTH-0430OperationLogoutUnknownOperationUnknown logout operation error
BP-AUTH-0440OperationSessionUnknownOperationUnknown session operation error
BP-AUTH-0450OperationGraphQLUnknownOperationUnknown GraphQL operation error
BP-AUTH-0500EdgeConfigUnknownEdge ConfigUnknown Edge Config error
BP-AUTH-0501EdgeConfigFetchEdge ConfigFailed to fetch Edge Config
BP-AUTH-0502EdgeConfigFetchUpdatedEdge ConfigFailed to fetch updated Edge Config
BP-AUTH-0503EdgeConfigUpdateEdge ConfigFailed to update Edge Config
BP-AUTH-0600EncryptionUnknownEncryptionUnknown encryption error
BP-AUTH-0700ValidationUnknownValidationUnknown validation error
BP-AUTH-0701ValidationApiUrlValidationInvalid API URL
BP-AUTH-0702ValidationMissingPropertiesValidationMissing required properties
BP-AUTH-0703ValidationInvalidPropertiesValidationInvalid property values
BP-AUTH-0800ClientUnknownClientUnknown client-side error
BP-AUTH-0802ClientHookUsedOutsideOfProviderClientReact hook used outside of AuthProvider

Usage

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

try {
await login({ context, input: { email, password } });
} catch (error) {
const errorCode = getErrorCode(error);

if (errorCode === BlueprintAuthErrorCode.TokenAccessInvalid) {
// handle invalid token
} else if (errorCode === BlueprintAuthErrorCode.ValidationMissingProperties) {
// handle validation error
}
}

ErrorCode

Union type of all possible error codes from Blueprint Auth and the Kraken API.

type ErrorCode = BlueprintAuthErrorCode | MappedKrakenErrorCode;

This type combines:


Constants

ConstantValueDescription
AUTH_COOKIE.accessToken"accessToken"Name of the access token cookie
AUTH_COOKIE.authProvider"authProvider"Name of the auth provider cookie
AUTH_COOKIE.MWAuthToken"MWAuthToken"Name of the MW auth token cookie
AUTH_COOKIE.MWRefreshToken"MWRefreshToken"Name of the MW refresh token cookie
AUTH_COOKIE.masqueradeToken"masqueradeToken"Name of the masquerade token cookie
AUTH_COOKIE.pkceVerifier"pkce-verifier"Name of the PKCE verifier cookie
AUTH_COOKIE.refreshToken"refreshToken"Name of the refresh token cookie
AUTH_COOKIE.scopedToken"scopedToken"Name of the scoped token cookie
AUTH_COOKIE.sub"sub"Name of the subject cookie

HTTP Headers

ConstantValueDescription
krakenAuthTokenOverrideHeader"x-kraken-auth-token-override"Header for token override in scoped requests
xClientIpHeader"x-kraken-client-ip"Header containing the client IP address
xClientIpAuthorizationHeader"x-kraken-client-ip-authorization"Header with signed client IP for rate-limiting prevention
xErrorPolicyHeader"x-error-policy"Per-request error policy override ("none", "ignore", "all")

URL Parameters

ConstantValueDescription
sessionQueryKey["auth"]Query key for session-related queries
ignoredQueryParams["nextPage"]Query parameters to ignore when constructing URLs
nextPageParam"nextPage"URL parameter for redirect destination after auth actions