Files
zitadel/packages/zitadel-client/src/node.ts
T
0945195f68 chore: deps update (#11968)
# Which Problems Are Solved
This pr updates major and minor dependencies and is the first step on
getting our dependabot alerts cut down.

# How the Problems Are Solved

Depedency updates across the board eg:
- Upgrade Angular to v21
- Upgrade next.js to v16.2
- Upgrade tailwind to v4 in the login
- Upgrade vitest to v4 in the login

This is an uncompleted list refer to the changed files for a full
overview of all the updates.

# Additional Changes

Migrated all control flow in the console to the modern control flow
syntax.
Fixed the dependsOn setting for the @zitadel/login:test-unit nx target.

# Additional Context

- Closes https://github.com/zitadel/zitadel/issues/11274

---------

Co-authored-by: Max Peintner <[email protected]>
2026-04-02 15:53:08 +02:00

101 lines
2.3 KiB
TypeScript

import { createPrivateKey } from "crypto";
import {
createGrpcTransport,
GrpcTransportOptions,
} from "@connectrpc/connect-node";
import {
createRemoteJWKSet,
importPKCS8,
jwtVerify,
JWTPayload,
SignJWT,
} from "jose";
import { NewAuthorizationBearerInterceptor } from "./interceptors.js";
/**
* Create a server transport using grpc with the given token and configuration options.
* @param token
* @param opts
*/
export function createServerTransport(
token: string,
opts: GrpcTransportOptions,
) {
return createGrpcTransport({
...opts,
interceptors: [
...(opts.interceptors || []),
NewAuthorizationBearerInterceptor(token),
],
});
}
/**
* Normalize a PEM private key to PKCS#8 format. Accepts both PKCS#1
* (BEGIN RSA PRIVATE KEY) and PKCS#8 (BEGIN PRIVATE KEY) inputs.
* Returns the key as a PKCS#8 PEM string.
*/
function toPKCS8(pem: string): string {
if (pem.includes("BEGIN PRIVATE KEY")) {
return pem;
}
return createPrivateKey(pem).export({
type: "pkcs8",
format: "pem",
}) as string;
}
export async function newSystemToken({
audience,
subject,
key,
expirationTime,
}: {
audience: string;
subject: string;
key: string;
expirationTime?: number | string | Date;
}) {
return await new SignJWT({})
.setProtectedHeader({ alg: "RS256" })
.setIssuedAt()
.setExpirationTime(expirationTime ?? "1h")
.setIssuer(subject)
.setSubject(subject)
.setAudience(audience)
.sign(await importPKCS8(toPKCS8(key), "RS256"));
}
/**
* Verify a signed JWT with the given keys endpoint.
* @param token
* @param keysEndpoint
* @param options
*/
export async function verifyJwt<T = JWTPayload>(
token: string,
keysEndpoint: string,
options?: {
issuer?: string;
audience?: string;
instanceHost?: string;
publicHost?: string;
},
): Promise<T & JWTPayload> {
const headers: Record<string, string> = {};
if (options?.instanceHost) {
headers["x-zitadel-instance-host"] = options.instanceHost;
}
if (options?.publicHost) {
headers["x-zitadel-public-host"] = options.publicHost;
}
const JWKS = createRemoteJWKSet(new URL(keysEndpoint), { headers: headers });
const { payload } = await jwtVerify(token, JWKS, {
issuer: options?.issuer,
audience: options?.audience,
});
return payload as T & JWTPayload;
}