Pkg/auth/0.4 - #45
Conversation
…ntation, and integrate @t3-oss/env-nextjs for secure configuration management
…nd standardized session keys across auth packages
There was a problem hiding this comment.
Pull request overview
This PR delivers a 0.4.0 release across @mayrlabs/auth and @mayrlabs/auth-nextjs, introducing remote JWKS support and stricter env-based configuration/validation, plus some unrelated prunejs test/tsconfig adjustments.
Changes:
- Add core constants and remote JWKS verification support in
@mayrlabs/auth(and update defaults like session key). - Refactor
@mayrlabs/auth-nextjsto validate configuration via@t3-oss/env-nextjs/zod, rely more on env vars, and addremotePublicKeysupport. - Add new unit tests in
packages/prunejsand adjust itstsconfig.jsoninclude list.
Reviewed changes
Copilot reviewed 20 out of 25 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/prunejs/tsconfig.json | Restricts TS include pattern to src/**/*. |
| packages/prunejs/src/test/utils/parser.test.ts | Adds parser utility unit tests. |
| packages/prunejs/src/test/utils/file-system.test.ts | Adds file-system utility unit tests. |
| packages/prunejs/src/test/utils/config.test.ts | Adds config loading/validation unit tests. |
| packages/prunejs/src/test/utils/analyzer.test.ts | Adds analyzer unit tests for unused code detection. |
| packages/auth/src/types.ts | Updates config types for optional publicKey + remotePublicKey and adds TSDoc. |
| packages/auth/src/index.ts | Exports new core/constants. |
| packages/auth/src/core/issuer.ts | Refines issuer signing methods and error-token signing payload. |
| packages/auth/src/core/constants.ts | Introduces shared constants (ACCOUNT_URL, ISSUER, SESSION_KEY, MACHINE_AUDIENCE). |
| packages/auth/src/core/client.ts | Switches default session key to shared constant and adds docs. |
| packages/auth/src/core/base.ts | Adds remote JWKS key support via createRemoteJWKSet and renames key getter to getVerifyKey. |
| packages/auth/src/core/base.test.ts | Updates tests for renamed getVerifyKey. |
| packages/auth/package.json | Bumps @mayrlabs/auth version to 0.4.0. |
| packages/auth/CHANGELOG.md | Documents 0.4.0 changes (remote JWK + constants + docs). |
| packages/auth/ABOUT.md | Updates documented default session key name. |
| packages/auth-nextjs/vitest.setup.ts | Adds shared env setup for tests. |
| packages/auth-nextjs/vitest.config.ts | Registers setupFiles for Vitest env initialization. |
| packages/auth-nextjs/src/types.ts | Updates Next.js integration options/types (adds remotePublicKey, removes issuer options). |
| packages/auth-nextjs/src/issuer/index.ts | Refactors issuer auth to createEnv/zod-validated env config and removes options. |
| packages/auth-nextjs/src/index.test.ts | Updates tests for env refactor and standardized session key. |
| packages/auth-nextjs/src/client/index.tsx | Adds env validation, supports remotePublicKey, standardizes session key, and uses audience env var in callback verification. |
| packages/auth-nextjs/README.md | Updates docs for new env vars and migration (incl. remote JWKS). |
| packages/auth-nextjs/package.json | Bumps version to 0.4.0 and adds env validation dependencies. |
| packages/auth-nextjs/CHANGELOG.md | Documents 0.4.0 changes and breaking issuer config change. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export const clientEnv = createEnv({ | ||
| server: { | ||
| MAYRLABS_AUTH_PUBLIC_JWK: z.string().optional(), | ||
| MAYRLABS_CLIENT_ID: z.string().min(1), | ||
| MAYRLABS_CLIENT_SECRET: z.string().min(1), | ||
| MAYRLABS_ACCOUNT_URL: z.string().url().default(ACCOUNT_URL), | ||
| MAYRLABS_CLIENT_AUDIENCE: z.string().min(1), | ||
| MAYRLABS_AUTH_ISSUER: z.string().optional(), | ||
| MAYRLABS_AUTH_SESSION_KEY: z.string().default(SESSION_KEY), | ||
| MAYRLABS_AUTH_ERROR_REDIRECT: z.string().default("/login"), | ||
| MAYRLABS_AUTH_SUCCESS_REDIRECT: z.string().default("/dashboard"), | ||
| }, | ||
| client: {}, | ||
| experimental__runtimeEnv: process.env, | ||
| skipValidation: process.env.NODE_ENV === "test", | ||
| }); |
There was a problem hiding this comment.
MAYRLABS_AUTH_PUBLIC_JWK is optional in the env schema, but if options.remotePublicKey is not enabled a missing public key will only fail later during token verification (throwing MISSING_PUBLIC_KEY). To preserve the PR’s “fail fast” config behavior, add an explicit initialization-time check that either remotePublicKey is true or publicKey is present, and throw a clear error message from createNextClientAuth().
| export const issuerEnv = createEnv({ | ||
| server: { | ||
| MAYRLABS_AUTH_PUBLIC_JWK: z.string().min(1), | ||
| MAYRLABS_AUTH_PRIVATE_JWK: z.string().min(1), | ||
| MAYRLABS_AUTH_ISSUER: z.string().min(1).default("auth.mayrlabs.com"), | ||
| MAYRLABS_AUTH_SESSION_KEY: z.string().default(SESSION_KEY), | ||
| MAYRLABS_AUTH_ERROR_REDIRECT: z.string().default("/login"), | ||
| }, |
There was a problem hiding this comment.
The env validation currently only checks that JWK env vars are non-empty strings, but the PR description claims validation fails fast when config is malformed. Consider refining MAYRLABS_AUTH_PUBLIC_JWK to validate it is valid JSON (and ideally shaped like a JWK) so malformed values error at startup rather than at first token verification.
| - `MAYRLABS_CLIENT_ID`: Your application's unique ID. | ||
| - `MAYRLABS_CLIENT_SECRET`: Your application's secret key (keep this server-side only). | ||
| - `MAYRLABS_ACCOUNT_URL`: (Optional) The URL of the central account system center. | ||
| The SDK now strictly validates environment variables using Zilch. Ensure the following are set in your `.env`: |
There was a problem hiding this comment.
The README says environment variables are validated using “Zilch”, but the implementation uses zod (and @t3-oss/env-nextjs). This is misleading to users and should be corrected.
| The SDK now strictly validates environment variables using Zilch. Ensure the following are set in your `.env`: | |
| The SDK now strictly validates environment variables using `zod` via `@t3-oss/env-nextjs`. Ensure the following are set in your `.env`: |
| export interface ClientConfigInput | ||
| extends Omit<ClientConfig, "redirects" | "session" | "issuer"> { | ||
| /** | ||
| * The issuer string representing the IDP token issuer length. |
There was a problem hiding this comment.
This TSDoc line reads “issuer length”, which looks like an accidental word and makes the description confusing. Update it to describe the issuer string (e.g., “issuer string representing the expected token issuer”).
| * The issuer string representing the IDP token issuer length. | |
| * The issuer string representing the expected IDP token issuer. |
| process.env.MAYRLABS_AUTH_PUBLIC_JWK = JSON.stringify({ | ||
| kty: "RSA", | ||
| n: "...", | ||
| e: "...", | ||
| }); | ||
| process.env.MAYRLABS_AUTH_PRIVATE_JWK = JSON.stringify({ | ||
| kty: "RSA", | ||
| n: "...", | ||
| e: "...", | ||
| }); | ||
| process.env.MAYRLABS_CLIENT_ID = "test-id"; | ||
| process.env.MAYRLABS_CLIENT_SECRET = "test-secret"; | ||
| process.env.MAYRLABS_ACCOUNT_URL = "https://testing.com"; | ||
| process.env.MAYRLABS_CLIENT_AUDIENCE = "test-audience"; | ||
| process.env.MAYRLABS_AUTH_ISSUER = "test-issuer"; | ||
| process.env.MAYRLABS_AUTH_SESSION_KEY = "mayrlabs-auth-session"; | ||
| process.env.MAYRLABS_AUTH_ERROR_REDIRECT = "/login"; | ||
| process.env.MAYRLABS_AUTH_SUCCESS_REDIRECT = "/dashboard"; | ||
|
|
There was a problem hiding this comment.
Now that vitest.config.ts sets setupFiles: ["./vitest.setup.ts"], these duplicated process.env.* assignments in the test file are redundant and can drift from the shared setup. Prefer keeping env initialization only in vitest.setup.ts and removing it from this test file.
| process.env.MAYRLABS_AUTH_PUBLIC_JWK = JSON.stringify({ | |
| kty: "RSA", | |
| n: "...", | |
| e: "...", | |
| }); | |
| process.env.MAYRLABS_AUTH_PRIVATE_JWK = JSON.stringify({ | |
| kty: "RSA", | |
| n: "...", | |
| e: "...", | |
| }); | |
| process.env.MAYRLABS_CLIENT_ID = "test-id"; | |
| process.env.MAYRLABS_CLIENT_SECRET = "test-secret"; | |
| process.env.MAYRLABS_ACCOUNT_URL = "https://testing.com"; | |
| process.env.MAYRLABS_CLIENT_AUDIENCE = "test-audience"; | |
| process.env.MAYRLABS_AUTH_ISSUER = "test-issuer"; | |
| process.env.MAYRLABS_AUTH_SESSION_KEY = "mayrlabs-auth-session"; | |
| process.env.MAYRLABS_AUTH_ERROR_REDIRECT = "/login"; | |
| process.env.MAYRLABS_AUTH_SUCCESS_REDIRECT = "/dashboard"; |
| export const clientEnv = createEnv({ | ||
| server: { | ||
| MAYRLABS_AUTH_PUBLIC_JWK: z.string().optional(), | ||
| MAYRLABS_CLIENT_ID: z.string().min(1), | ||
| MAYRLABS_CLIENT_SECRET: z.string().min(1), | ||
| MAYRLABS_ACCOUNT_URL: z.string().url().default(ACCOUNT_URL), | ||
| MAYRLABS_CLIENT_AUDIENCE: z.string().min(1), | ||
| MAYRLABS_AUTH_ISSUER: z.string().optional(), | ||
| MAYRLABS_AUTH_SESSION_KEY: z.string().default(SESSION_KEY), | ||
| MAYRLABS_AUTH_ERROR_REDIRECT: z.string().default("/login"), | ||
| MAYRLABS_AUTH_SUCCESS_REDIRECT: z.string().default("/dashboard"), | ||
| }, |
There was a problem hiding this comment.
Similar to issuer env validation: MAYRLABS_AUTH_PUBLIC_JWK is accepted as an arbitrary string (when provided). If the goal is strict env validation, consider refining it to ensure it’s valid JSON (and a plausible JWK) so misconfiguration is caught at startup rather than during the first verification call.
|
|
||
| const user = await setup.verifyAuthToken(token); | ||
| const user = await setup.verifyAuthToken(token, audience); | ||
|
|
||
| if (!user) { | ||
| return redirectToError( |
There was a problem hiding this comment.
handleCallback() now verifies tokens using the configured MAYRLABS_CLIENT_AUDIENCE (good), but other flows in this module still call setup.verifyAuthToken(token) without passing audience (e.g. getUser() / authProxy() / AuthProvider() via getUser()). Since ClientAuthSetup defaults audience to clientId, this can make session-cookie verification fail after a successful callback, or validate against an unintended audience. Please thread audience through all verifyAuthToken calls in this module for consistency.
| protected async getVerifyKey(): Promise<CryptoKey | JWTVerifyGetKey> { | ||
| if (this.config.remotePublicKey && this.config.accountUrl) { | ||
| this._jwks ??= createRemoteJWKSet( | ||
| new URL(`${this.config.accountUrl}/.well-known/jwks.json`), | ||
| ); | ||
|
|
||
| return this._jwks; | ||
| } |
There was a problem hiding this comment.
Remote JWKS verification is new behavior (remotePublicKey + accountUrl → createRemoteJWKSet(...)), but the existing BaseAuthSetup tests only cover local key import/caching. Add a focused unit test that enables remotePublicKey and asserts getVerifyKey() returns/caches a JWKS getter (and that jwtVerify is invoked with it) to prevent regressions.
Introduce a jwkSchema (Zod) to validate JWKs and use it in both issuer and client env parsing. Enforce that either a remote public key is used or an env-provided public JWK is present, and improve error messages for unauthenticated cases. Fix session cookie key usage and ensure verifyAuthToken is called with audience where appropriate; adjust logout/redirect handling to use configured redirects. Update tests to mock remote JWKS and cover caching behavior, and remove hardcoded env setup from client tests. Also bump @mayrlabs/auth dependency version in auth-nextjs and correct a README typo (Zilch -> Zod).
This pull request introduces a major 0.4.0 release for
@mayrlabs/auth-nextjs, focusing on strict environment validation and improved configuration consistency. The most significant changes include enforcing runtime environment variable validation using@t3-oss/env-nextjsandzod, refactoring configuration to rely solely on environment variables (removing most options fromcreateNextIssuerAuth), supporting remote JWK fetching, and standardizing session cookie naming. Documentation and tests have also been updated to reflect these changes.Environment Validation and Configuration:
Integrated
@t3-oss/env-nextjsandzodto strictly validate all required authentication environment variables at runtime. The SDK now fails fast if configuration is missing or malformed, improving reliability and security. All configuration for both client and issuer auth is now handled via environment variables, with sensible defaults and clear error messages. (packages/auth-nextjs/src/client/index.tsx,packages/auth-nextjs/src/issuer/index.ts,packages/auth-nextjs/README.md,packages/auth-nextjs/CHANGELOG.md, [1] [2] [3] [4]createNextIssuerAuth()no longer accepts options for session keys or redirects; these are now determined solely by environment variables, representing a breaking change for issuer configuration. (packages/auth-nextjs/src/issuer/index.ts,packages/auth-nextjs/README.md, [1] [2]Feature Enhancements:
Added support for the
remotePublicKeyoption increateNextClientAuth, allowing public keys to be fetched automatically from the identity provider's JWKS endpoint, reducing manual configuration. (packages/auth-nextjs/src/client/index.tsx,packages/auth-nextjs/src/types.ts, [1] [2]Standardized the session cookie key to
mayrlabs-auth-sessionacross the ecosystem for better consistency. (packages/auth-nextjs/src/client/index.tsx,packages/auth-nextjs/src/issuer/index.ts, [1] [2]Documentation and Testing:
Updated and expanded TSDoc and README documentation to clearly describe all environment variables, defaults, and usage patterns, including migration notes for the breaking changes. (
packages/auth-nextjs/README.md,packages/auth-nextjs/CHANGELOG.md, [1] [2]Refactored tests and test setup to align with the new environment variable validation approach, removing tests for missing variables (since validation is now centralized) and setting up environment variables in a single place for consistency. (
packages/auth-nextjs/src/index.test.ts,packages/auth-nextjs/vitest.setup.ts, [1] [2] [3]Dependency Updates:
@t3-oss/env-nextjsandzodas dependencies to enable strict environment validation. (packages/auth-nextjs/package.json, packages/auth-nextjs/package.jsonL119-R121)Versioning:
0.4.0to reflect these major and breaking changes. (packages/auth-nextjs/package.json, packages/auth-nextjs/package.jsonL3-R3)