@jmlq/auth-plugin-jose is the infrastructure plugin that implements ITokenServicePort from @jmlq/auth using the jose library.
Its real responsibility is:
- generate access tokens and refresh tokens,
- verify signed tokens,
- normalize cryptographic configuration,
- translate technical errors from
joseinto core-compatible errors.
The recommended entry point is createJoseTokenService(...).
This plugin allows the @jmlq/auth core to remain independent from the specific JWT technology.
In practice:
- the core depends on
ITokenServicePort, - this plugin implements that contract,
- the host decides whether to use
HS256,RS256, orES256, - business logic remains in
@jmlq/auth.
createJoseTokenService(...)validates minimal preconditions and buildsJoseTokenService.JoseTokenServiceencapsulatesSignJWT,jwtVerify,decodeJwt,importPKCS8, andimportSPKI.jose-error.mapper.tstranslates technical errors into core error codes.audienceis used only for issuing; it is not passed tojwtVerifyduring verification.
β‘οΈ See details in: architecture.md
npm i @jmlq/auth @jmlq/auth-plugin-jose joseDirect dependencies of the package:
@jmlq/authjose
Recommended real usage from infrastructure:
import { createJoseTokenService } from "@jmlq/auth-plugin-jose";
const tokenService = createJoseTokenService(
{
keyMaterial: {
alg: "RS256",
privateKey: process.env.JWT_PRIVATE_KEY!,
publicKey: process.env.JWT_PUBLIC_KEY!,
},
issuer: process.env.JWT_ISSUER,
audience: process.env.JWT_AUDIENCE,
clockSkewSeconds: Number(process.env.JWT_CLOCK_SKEW_SECONDS ?? 5),
defaultExpiresIn: {
accessToken: "15m",
refreshToken: "7d",
},
},
{
createAuthError,
},
);Also valid with HS256:
const tokenService = createJoseTokenService(
{
keyMaterial: {
alg: "HS256",
secret: process.env.JWT_SECRET!,
},
issuer: process.env.JWT_ISSUER,
audience: process.env.JWT_AUDIENCE,
defaultExpiresIn: {
accessToken: "15m",
refreshToken: "7d",
},
},
{ createAuthError },
);The plugin does not read .env directly.
The host resolves variables and builds JoseTokenServiceOptions.
Typical variables consistent with this integration:
process.env.JWT_SECRET;
process.env.JWT_PRIVATE_KEY;
process.env.JWT_PUBLIC_KEY;
process.env.JWT_ISSUER;
process.env.JWT_AUDIENCE;
process.env.JWT_CLOCK_SKEW_SECONDS;Real signature:
createJoseTokenService(
options: JoseTokenServiceOptions,
deps: { createAuthError: CreateAuthErrorFn },
)Real responsibilities:
- validate
keyMaterial, - require
createAuthError, - build a concrete implementation of
ITokenServicePort.
Real public configuration:
export interface JoseTokenServiceOptions {
keyMaterial: JoseKeyMaterial;
issuer?: string;
audience?: string | string[];
clockSkewSeconds?: number;
defaultExpiresIn?: {
accessToken?: string;
refreshToken?: string;
};
}type JoseKeyMaterial =
| { alg: "HS256"; secret: string }
| { alg: "RS256" | "ES256"; privateKey: string; publicKey: string };The plugin validates:
HS256requiressecretRS256/ES256requireprivateKeyandpublicKey
Real rule implemented in the plugin:
audienceis used for signing (jwt.setAudience(...))audienceis not passed tojwtVerify(...)
This prevents turning aud into a mandatory requirement during verification.
