Buckets:
| // src/utils/jwt/jws.ts | |
| import { getRuntimeKey } from "../../helper/adapter/index.js"; | |
| import { decodeBase64 } from "../encode.js"; | |
| import { CryptoKeyUsage, JwtAlgorithmNotImplemented } from "./types.js"; | |
| import { utf8Encoder } from "./utf8.js"; | |
| async function signing(privateKey, alg, data) { | |
| const algorithm = getKeyAlgorithm(alg); | |
| const cryptoKey = await importPrivateKey(privateKey, algorithm); | |
| return await crypto.subtle.sign(algorithm, cryptoKey, data); | |
| } | |
| async function verifying(publicKey, alg, signature, data) { | |
| const algorithm = getKeyAlgorithm(alg); | |
| const cryptoKey = await importPublicKey(publicKey, algorithm); | |
| return await crypto.subtle.verify(algorithm, cryptoKey, signature, data); | |
| } | |
| function pemToBinary(pem) { | |
| return decodeBase64(pem.replace(/-+(BEGIN|END).*/g, "").replace(/\s/g, "")); | |
| } | |
| async function importPrivateKey(key, alg) { | |
| if (!crypto.subtle || !crypto.subtle.importKey) { | |
| throw new Error("`crypto.subtle.importKey` is undefined. JWT auth middleware requires it."); | |
| } | |
| if (isCryptoKey(key)) { | |
| if (key.type !== "private" && key.type !== "secret") { | |
| throw new Error( | |
| `unexpected key type: CryptoKey.type is ${key.type}, expected private or secret` | |
| ); | |
| } | |
| return key; | |
| } | |
| const usages = [CryptoKeyUsage.Sign]; | |
| if (typeof key === "object") { | |
| return await crypto.subtle.importKey("jwk", key, alg, false, usages); | |
| } | |
| if (key.includes("PRIVATE")) { | |
| return await crypto.subtle.importKey("pkcs8", pemToBinary(key), alg, false, usages); | |
| } | |
| return await crypto.subtle.importKey("raw", utf8Encoder.encode(key), alg, false, usages); | |
| } | |
| async function importPublicKey(key, alg) { | |
| if (!crypto.subtle || !crypto.subtle.importKey) { | |
| throw new Error("`crypto.subtle.importKey` is undefined. JWT auth middleware requires it."); | |
| } | |
| if (isCryptoKey(key)) { | |
| if (key.type === "public" || key.type === "secret") { | |
| return key; | |
| } | |
| key = await exportPublicJwkFrom(key); | |
| } | |
| if (typeof key === "string" && key.includes("PRIVATE")) { | |
| const privateKey = await crypto.subtle.importKey("pkcs8", pemToBinary(key), alg, true, [ | |
| CryptoKeyUsage.Sign | |
| ]); | |
| key = await exportPublicJwkFrom(privateKey); | |
| } | |
| const usages = [CryptoKeyUsage.Verify]; | |
| if (typeof key === "object") { | |
| return await crypto.subtle.importKey("jwk", key, alg, false, usages); | |
| } | |
| if (key.includes("PUBLIC")) { | |
| return await crypto.subtle.importKey("spki", pemToBinary(key), alg, false, usages); | |
| } | |
| return await crypto.subtle.importKey("raw", utf8Encoder.encode(key), alg, false, usages); | |
| } | |
| async function exportPublicJwkFrom(privateKey) { | |
| if (privateKey.type !== "private") { | |
| throw new Error(`unexpected key type: ${privateKey.type}`); | |
| } | |
| if (!privateKey.extractable) { | |
| throw new Error("unexpected private key is unextractable"); | |
| } | |
| const jwk = await crypto.subtle.exportKey("jwk", privateKey); | |
| const { kty } = jwk; | |
| const { alg, e, n } = jwk; | |
| const { crv, x, y } = jwk; | |
| return { kty, alg, e, n, crv, x, y, key_ops: [CryptoKeyUsage.Verify] }; | |
| } | |
| function getKeyAlgorithm(name) { | |
| switch (name) { | |
| case "HS256": | |
| return { | |
| name: "HMAC", | |
| hash: { | |
| name: "SHA-256" | |
| } | |
| }; | |
| case "HS384": | |
| return { | |
| name: "HMAC", | |
| hash: { | |
| name: "SHA-384" | |
| } | |
| }; | |
| case "HS512": | |
| return { | |
| name: "HMAC", | |
| hash: { | |
| name: "SHA-512" | |
| } | |
| }; | |
| case "RS256": | |
| return { | |
| name: "RSASSA-PKCS1-v1_5", | |
| hash: { | |
| name: "SHA-256" | |
| } | |
| }; | |
| case "RS384": | |
| return { | |
| name: "RSASSA-PKCS1-v1_5", | |
| hash: { | |
| name: "SHA-384" | |
| } | |
| }; | |
| case "RS512": | |
| return { | |
| name: "RSASSA-PKCS1-v1_5", | |
| hash: { | |
| name: "SHA-512" | |
| } | |
| }; | |
| case "PS256": | |
| return { | |
| name: "RSA-PSS", | |
| hash: { | |
| name: "SHA-256" | |
| }, | |
| saltLength: 32 | |
| // 256 >> 3 | |
| }; | |
| case "PS384": | |
| return { | |
| name: "RSA-PSS", | |
| hash: { | |
| name: "SHA-384" | |
| }, | |
| saltLength: 48 | |
| // 384 >> 3 | |
| }; | |
| case "PS512": | |
| return { | |
| name: "RSA-PSS", | |
| hash: { | |
| name: "SHA-512" | |
| }, | |
| saltLength: 64 | |
| // 512 >> 3, | |
| }; | |
| case "ES256": | |
| return { | |
| name: "ECDSA", | |
| hash: { | |
| name: "SHA-256" | |
| }, | |
| namedCurve: "P-256" | |
| }; | |
| case "ES384": | |
| return { | |
| name: "ECDSA", | |
| hash: { | |
| name: "SHA-384" | |
| }, | |
| namedCurve: "P-384" | |
| }; | |
| case "ES512": | |
| return { | |
| name: "ECDSA", | |
| hash: { | |
| name: "SHA-512" | |
| }, | |
| namedCurve: "P-521" | |
| }; | |
| case "EdDSA": | |
| return { | |
| name: "Ed25519", | |
| namedCurve: "Ed25519" | |
| }; | |
| default: | |
| throw new JwtAlgorithmNotImplemented(name); | |
| } | |
| } | |
| function isCryptoKey(key) { | |
| const runtime = getRuntimeKey(); | |
| if (runtime === "node" && !!crypto.webcrypto) { | |
| return key instanceof crypto.webcrypto.CryptoKey; | |
| } | |
| return key instanceof CryptoKey; | |
| } | |
| export { | |
| signing, | |
| verifying | |
| }; | |
Xet Storage Details
- Size:
- 5.18 kB
- Xet hash:
- 8a1f3235c421be073900044ed5a5911cdfd91bdf7208f5bac11e25b79001d3aa
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.