@ricsam/quickjs-crypto 0.0.1 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/crypto-key.cjs +70 -0
- package/dist/cjs/crypto-key.cjs.map +10 -0
- package/dist/cjs/index.cjs +41 -0
- package/dist/cjs/index.cjs.map +10 -0
- package/dist/cjs/package.json +5 -0
- package/dist/cjs/random.cjs +89 -0
- package/dist/cjs/random.cjs.map +10 -0
- package/dist/cjs/setup.cjs +88 -0
- package/dist/cjs/setup.cjs.map +10 -0
- package/dist/cjs/subtle-crypto.cjs +307 -0
- package/dist/cjs/subtle-crypto.cjs.map +10 -0
- package/dist/cjs/types.cjs +26 -0
- package/dist/cjs/types.cjs.map +9 -0
- package/dist/mjs/crypto-key.mjs +39 -0
- package/dist/mjs/crypto-key.mjs.map +10 -0
- package/dist/mjs/index.mjs +10 -0
- package/dist/mjs/index.mjs.map +10 -0
- package/dist/mjs/package.json +5 -0
- package/dist/mjs/random.mjs +58 -0
- package/dist/mjs/random.mjs.map +10 -0
- package/dist/mjs/setup.mjs +60 -0
- package/dist/mjs/setup.mjs.map +10 -0
- package/dist/mjs/subtle-crypto.mjs +282 -0
- package/dist/mjs/subtle-crypto.mjs.map +10 -0
- package/dist/mjs/types.mjs +3 -0
- package/dist/mjs/types.mjs.map +9 -0
- package/dist/types/crypto-key.d.ts +10 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/quickjs.d.ts +287 -0
- package/dist/types/random.d.ts +14 -0
- package/dist/types/setup.d.ts +43 -0
- package/dist/types/subtle-crypto.d.ts +12 -0
- package/dist/types/types.d.ts +44 -0
- package/package.json +54 -6
- package/README.md +0 -45
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/subtle-crypto.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { QuickJSContext, QuickJSHandle } from \"quickjs-emscripten\";\nimport type { CryptoKeyState, KeyUsage } from \"./types.mjs\";\nimport {\n nextInstanceId,\n registerInstance,\n getInstanceStateById,\n marshal,\n unmarshal,\n} from \"@ricsam/quickjs-core\";\n\n/**\n * Helper to create a CryptoKey instance in QuickJS from a host CryptoKey\n *\n * This registers the host key in our state management and creates\n * a QuickJS CryptoKey object that references it via __instanceId__\n */\nexport function createCryptoKeyInstance(\n context: QuickJSContext,\n hostKey: globalThis.CryptoKey\n): QuickJSHandle {\n const instanceId = nextInstanceId();\n\n const state: CryptoKeyState = {\n hostKey,\n type: hostKey.type,\n extractable: hostKey.extractable,\n algorithm: hostKey.algorithm as KeyAlgorithm,\n usages: Array.from(hostKey.usages) as KeyUsage[],\n };\n\n registerInstance(instanceId, \"CryptoKey\", state);\n\n // Create instance via evalCode to properly instantiate with prototype chain\n const result = context.evalCode(`\n (function() {\n const key = Object.create(CryptoKey.prototype);\n Object.defineProperty(key, '__instanceId__', {\n value: ${instanceId},\n enumerable: false,\n writable: false,\n configurable: false\n });\n return key;\n })()\n `);\n\n if (result.error) {\n const err = context.dump(result.error);\n result.error.dispose();\n throw new Error(`Failed to create CryptoKey instance: ${JSON.stringify(err)}`);\n }\n\n return result.value;\n}\n\n/**\n * Helper to create a CryptoKeyPair object in QuickJS\n */\nfunction createCryptoKeyPairInstance(\n context: QuickJSContext,\n keyPair: globalThis.CryptoKeyPair\n): QuickJSHandle {\n const publicKeyHandle = createCryptoKeyInstance(context, keyPair.publicKey);\n const privateKeyHandle = createCryptoKeyInstance(context, keyPair.privateKey);\n\n const obj = context.newObject();\n context.setProp(obj, \"publicKey\", publicKeyHandle);\n context.setProp(obj, \"privateKey\", privateKeyHandle);\n\n publicKeyHandle.dispose();\n privateKeyHandle.dispose();\n\n return obj;\n}\n\n/**\n * Helper to get the host CryptoKey from a QuickJS CryptoKey handle\n */\nfunction getHostKey(context: QuickJSContext, keyHandle: QuickJSHandle): globalThis.CryptoKey {\n const instanceIdHandle = context.getProp(keyHandle, \"__instanceId__\");\n if (context.typeof(instanceIdHandle) !== \"number\") {\n instanceIdHandle.dispose();\n throw new Error(\"Invalid CryptoKey: missing __instanceId__\");\n }\n\n const instanceId = context.getNumber(instanceIdHandle);\n instanceIdHandle.dispose();\n\n const state = getInstanceStateById<CryptoKeyState>(instanceId);\n if (!state) {\n throw new Error(\"Invalid CryptoKey: state not found\");\n }\n\n return state.hostKey;\n}\n\n/**\n * Helper to safely get an argument from the args array\n */\nfunction getArg(args: QuickJSHandle[], index: number): QuickJSHandle {\n const arg = args[index];\n if (!arg) {\n throw new Error(`Missing argument at index ${index}`);\n }\n return arg;\n}\n\n/**\n * Create an async SubtleCrypto method that handles CryptoKey marshalling\n *\n * @param unmarshalArgs - Function to unmarshal arguments synchronously before async work\n * @param implementation - Async implementation that receives unmarshaled args\n */\nfunction createSubtleMethod<T>(\n context: QuickJSContext,\n methodName: string,\n unmarshalArgs: (context: QuickJSContext, args: QuickJSHandle[]) => T,\n implementation: (context: QuickJSContext, unmarshaledArgs: T) => Promise<QuickJSHandle>\n): QuickJSHandle {\n return context.newFunction(methodName, (...args) => {\n const deferred = context.newPromise();\n\n // Unmarshal arguments synchronously BEFORE scheduling async work\n // This is critical because the QuickJS handles may be disposed before the microtask runs\n let unmarshaledArgs: T;\n try {\n unmarshaledArgs = unmarshalArgs(context, args);\n } catch (error) {\n // If unmarshalling fails, reject immediately\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n context.runtime.executePendingJobs();\n return deferred.handle;\n }\n\n // Run the async implementation in a microtask\n Promise.resolve().then(async () => {\n try {\n const resultHandle = await implementation(context, unmarshaledArgs);\n deferred.resolve(resultHandle);\n resultHandle.dispose();\n } catch (error) {\n // Use marshal instead of newError to avoid issues with disposed context\n const errorHandle = marshal(context, {\n name: error instanceof Error ? error.name : \"Error\",\n message: error instanceof Error ? error.message : String(error),\n });\n deferred.reject(errorHandle);\n errorHandle.dispose();\n }\n context.runtime.executePendingJobs();\n });\n\n return deferred.handle;\n });\n}\n\n// Type definitions for unmarshaled args\ninterface DigestArgs {\n algorithm: AlgorithmIdentifier;\n data: Uint8Array;\n}\n\ninterface GenerateKeyArgs {\n algorithm: RsaHashedKeyGenParams | EcKeyGenParams | AesKeyGenParams | HmacKeyGenParams;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface SignArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n data: Uint8Array;\n}\n\ninterface VerifyArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n signature: Uint8Array;\n data: Uint8Array;\n}\n\ninterface EncryptDecryptArgs {\n algorithm: AlgorithmIdentifier;\n key: globalThis.CryptoKey;\n data: Uint8Array;\n}\n\ninterface ImportKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n keyData: Uint8Array | JsonWebKey;\n algorithm: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface ExportKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n key: globalThis.CryptoKey;\n}\n\ninterface DeriveBitsArgs {\n algorithm: Record<string, unknown>;\n baseKey: globalThis.CryptoKey;\n length: number;\n}\n\ninterface DeriveKeyArgs {\n algorithm: Record<string, unknown>;\n baseKey: globalThis.CryptoKey;\n derivedKeyType: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\ninterface WrapKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n key: globalThis.CryptoKey;\n wrappingKey: globalThis.CryptoKey;\n wrapAlgorithm: AlgorithmIdentifier;\n}\n\ninterface UnwrapKeyArgs {\n format: \"raw\" | \"pkcs8\" | \"spki\" | \"jwk\";\n wrappedKey: Uint8Array;\n unwrappingKey: globalThis.CryptoKey;\n unwrapAlgorithm: AlgorithmIdentifier;\n unwrappedKeyAlgorithm: AlgorithmIdentifier;\n extractable: boolean;\n keyUsages: globalThis.KeyUsage[];\n}\n\n/**\n * Create the SubtleCrypto object with all methods\n */\nexport function createSubtleCryptoObject(context: QuickJSContext): QuickJSHandle {\n const subtle = context.newObject();\n\n // digest(algorithm, data) -> ArrayBuffer\n const digestFn = createSubtleMethod<DigestArgs>(\n context,\n \"digest\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n data: unmarshal(ctx, getArg(args, 1)) as Uint8Array,\n }),\n async (ctx, { algorithm, data }) => {\n const result = await crypto.subtle.digest(algorithm, data as unknown as BufferSource);\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"digest\", digestFn);\n digestFn.dispose();\n\n // generateKey(algorithm, extractable, keyUsages) -> CryptoKey | CryptoKeyPair\n const generateKeyFn = createSubtleMethod<GenerateKeyArgs>(\n context,\n \"generateKey\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as GenerateKeyArgs[\"algorithm\"],\n extractable: unmarshal(ctx, getArg(args, 1)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 2)) as globalThis.KeyUsage[],\n }),\n async (ctx, { algorithm, extractable, keyUsages }) => {\n const result = await crypto.subtle.generateKey(algorithm, extractable, keyUsages);\n\n // Check if it's a key pair or single key\n if (\"publicKey\" in result && \"privateKey\" in result) {\n return createCryptoKeyPairInstance(ctx, result);\n } else {\n return createCryptoKeyInstance(ctx, result as globalThis.CryptoKey);\n }\n }\n );\n context.setProp(subtle, \"generateKey\", generateKeyFn);\n generateKeyFn.dispose();\n\n // sign(algorithm, key, data) -> ArrayBuffer\n const signFn = createSubtleMethod<SignArgs>(\n context,\n \"sign\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async (ctx, { algorithm, key, data }) => {\n const result = await crypto.subtle.sign(algorithm, key, data as unknown as BufferSource);\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"sign\", signFn);\n signFn.dispose();\n\n // verify(algorithm, key, signature, data) -> boolean\n const verifyFn = createSubtleMethod<VerifyArgs>(\n context,\n \"verify\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n signature: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n data: unmarshal(ctx, getArg(args, 3)) as Uint8Array,\n }),\n async (ctx, { algorithm, key, signature, data }) => {\n const result = await crypto.subtle.verify(\n algorithm,\n key,\n signature as unknown as BufferSource,\n data as unknown as BufferSource\n );\n return marshal(ctx, result);\n }\n );\n context.setProp(subtle, \"verify\", verifyFn);\n verifyFn.dispose();\n\n // encrypt(algorithm, key, data) -> ArrayBuffer\n const encryptFn = createSubtleMethod<EncryptDecryptArgs>(\n context,\n \"encrypt\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async (ctx, { algorithm, key, data }) => {\n const result = await crypto.subtle.encrypt(\n algorithm,\n key,\n data as unknown as BufferSource\n );\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"encrypt\", encryptFn);\n encryptFn.dispose();\n\n // decrypt(algorithm, key, data) -> ArrayBuffer\n const decryptFn = createSubtleMethod<EncryptDecryptArgs>(\n context,\n \"decrypt\",\n (ctx, args) => ({\n algorithm: unmarshal(ctx, getArg(args, 0)) as AlgorithmIdentifier,\n key: getHostKey(ctx, getArg(args, 1)),\n data: unmarshal(ctx, getArg(args, 2)) as Uint8Array,\n }),\n async (ctx, { algorithm, key, data }) => {\n const result = await crypto.subtle.decrypt(\n algorithm,\n key,\n data as unknown as BufferSource\n );\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"decrypt\", decryptFn);\n decryptFn.dispose();\n\n // importKey(format, keyData, algorithm, extractable, keyUsages) -> CryptoKey\n const importKeyFn = createSubtleMethod<ImportKeyArgs>(\n context,\n \"importKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as ImportKeyArgs[\"format\"],\n keyData: unmarshal(ctx, getArg(args, 1)) as Uint8Array | JsonWebKey,\n algorithm: unmarshal(ctx, getArg(args, 2)) as AlgorithmIdentifier,\n extractable: unmarshal(ctx, getArg(args, 3)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 4)) as globalThis.KeyUsage[],\n }),\n async (ctx, { format, keyData, algorithm, extractable, keyUsages }) => {\n let result: globalThis.CryptoKey;\n\n if (format === \"jwk\") {\n // JWK format expects JsonWebKey\n result = await crypto.subtle.importKey(\n format,\n keyData as JsonWebKey,\n algorithm,\n extractable,\n keyUsages\n );\n } else {\n // Non-jwk formats expect BufferSource\n // Convert Uint8Array to ArrayBuffer\n let data: BufferSource;\n if (keyData instanceof Uint8Array) {\n data = keyData.buffer.slice(keyData.byteOffset, keyData.byteOffset + keyData.byteLength) as ArrayBuffer;\n } else {\n data = keyData as BufferSource;\n }\n\n result = await crypto.subtle.importKey(\n format,\n data,\n algorithm,\n extractable,\n keyUsages\n ) as globalThis.CryptoKey;\n }\n\n return createCryptoKeyInstance(ctx, result);\n }\n );\n context.setProp(subtle, \"importKey\", importKeyFn);\n importKeyFn.dispose();\n\n // exportKey(format, key) -> ArrayBuffer | JsonWebKey\n const exportKeyFn = createSubtleMethod<ExportKeyArgs>(\n context,\n \"exportKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as ExportKeyArgs[\"format\"],\n key: getHostKey(ctx, getArg(args, 1)),\n }),\n async (ctx, { format, key }) => {\n const result = await crypto.subtle.exportKey(format, key);\n\n if (result instanceof ArrayBuffer) {\n return marshal(ctx, new Uint8Array(result));\n } else {\n // JsonWebKey - marshal as plain object\n return marshal(ctx, result);\n }\n }\n );\n context.setProp(subtle, \"exportKey\", exportKeyFn);\n exportKeyFn.dispose();\n\n // deriveBits(algorithm, baseKey, length) -> ArrayBuffer\n const deriveBitsFn = createSubtleMethod<DeriveBitsArgs>(\n context,\n \"deriveBits\",\n (ctx, args) => {\n const algorithmRaw = unmarshal(ctx, getArg(args, 0)) as Record<string, unknown>;\n const baseKey = getHostKey(ctx, getArg(args, 1));\n const length = unmarshal(ctx, getArg(args, 2)) as number;\n\n // If the algorithm has a 'public' property, it needs to be a CryptoKey\n let algorithm = algorithmRaw;\n if (algorithmRaw.public && typeof algorithmRaw.public === \"object\") {\n const publicKeyData = algorithmRaw.public as { __instanceId__?: number };\n if (publicKeyData.__instanceId__ !== undefined) {\n const publicKeyState = getInstanceStateById<CryptoKeyState>(publicKeyData.__instanceId__);\n if (publicKeyState) {\n algorithm = { ...algorithmRaw, public: publicKeyState.hostKey };\n }\n }\n }\n\n return { algorithm, baseKey, length };\n },\n async (ctx, { algorithm, baseKey, length }) => {\n const result = await crypto.subtle.deriveBits(\n algorithm as unknown as AlgorithmIdentifier,\n baseKey,\n length\n );\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"deriveBits\", deriveBitsFn);\n deriveBitsFn.dispose();\n\n // deriveKey(algorithm, baseKey, derivedKeyType, extractable, keyUsages) -> CryptoKey\n const deriveKeyFn = createSubtleMethod<DeriveKeyArgs>(\n context,\n \"deriveKey\",\n (ctx, args) => {\n const algorithmRaw = unmarshal(ctx, getArg(args, 0)) as Record<string, unknown>;\n const baseKey = getHostKey(ctx, getArg(args, 1));\n const derivedKeyType = unmarshal(ctx, getArg(args, 2)) as AlgorithmIdentifier;\n const extractable = unmarshal(ctx, getArg(args, 3)) as boolean;\n const keyUsages = unmarshal(ctx, getArg(args, 4)) as globalThis.KeyUsage[];\n\n // If the algorithm has a 'public' property, it needs to be a CryptoKey\n let algorithm = algorithmRaw;\n if (algorithmRaw.public && typeof algorithmRaw.public === \"object\") {\n const publicKeyData = algorithmRaw.public as { __instanceId__?: number };\n if (publicKeyData.__instanceId__ !== undefined) {\n const publicKeyState = getInstanceStateById<CryptoKeyState>(publicKeyData.__instanceId__);\n if (publicKeyState) {\n algorithm = { ...algorithmRaw, public: publicKeyState.hostKey };\n }\n }\n }\n\n return { algorithm, baseKey, derivedKeyType, extractable, keyUsages };\n },\n async (ctx, { algorithm, baseKey, derivedKeyType, extractable, keyUsages }) => {\n const result = await crypto.subtle.deriveKey(\n algorithm as unknown as AlgorithmIdentifier,\n baseKey,\n derivedKeyType,\n extractable,\n keyUsages\n );\n\n return createCryptoKeyInstance(ctx, result as globalThis.CryptoKey);\n }\n );\n context.setProp(subtle, \"deriveKey\", deriveKeyFn);\n deriveKeyFn.dispose();\n\n // wrapKey(format, key, wrappingKey, wrapAlgorithm) -> ArrayBuffer\n const wrapKeyFn = createSubtleMethod<WrapKeyArgs>(\n context,\n \"wrapKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as WrapKeyArgs[\"format\"],\n key: getHostKey(ctx, getArg(args, 1)),\n wrappingKey: getHostKey(ctx, getArg(args, 2)),\n wrapAlgorithm: unmarshal(ctx, getArg(args, 3)) as AlgorithmIdentifier,\n }),\n async (ctx, { format, key, wrappingKey, wrapAlgorithm }) => {\n const result = await crypto.subtle.wrapKey(format, key, wrappingKey, wrapAlgorithm);\n return marshal(ctx, new Uint8Array(result));\n }\n );\n context.setProp(subtle, \"wrapKey\", wrapKeyFn);\n wrapKeyFn.dispose();\n\n // unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages) -> CryptoKey\n const unwrapKeyFn = createSubtleMethod<UnwrapKeyArgs>(\n context,\n \"unwrapKey\",\n (ctx, args) => ({\n format: unmarshal(ctx, getArg(args, 0)) as UnwrapKeyArgs[\"format\"],\n wrappedKey: unmarshal(ctx, getArg(args, 1)) as Uint8Array,\n unwrappingKey: getHostKey(ctx, getArg(args, 2)),\n unwrapAlgorithm: unmarshal(ctx, getArg(args, 3)) as AlgorithmIdentifier,\n unwrappedKeyAlgorithm: unmarshal(ctx, getArg(args, 4)) as AlgorithmIdentifier,\n extractable: unmarshal(ctx, getArg(args, 5)) as boolean,\n keyUsages: unmarshal(ctx, getArg(args, 6)) as globalThis.KeyUsage[],\n }),\n async (ctx, { format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages }) => {\n const result = await crypto.subtle.unwrapKey(\n format,\n wrappedKey as unknown as BufferSource,\n unwrappingKey,\n unwrapAlgorithm,\n unwrappedKeyAlgorithm,\n extractable,\n keyUsages\n );\n\n return createCryptoKeyInstance(ctx, result as globalThis.CryptoKey);\n }\n );\n context.setProp(subtle, \"unwrapKey\", unwrapKeyFn);\n unwrapKeyFn.dispose();\n\n return subtle;\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "447E4B44811F04E864756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
|
|
2
|
+
import type { StateMap } from "./types.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Create the CryptoKey class for the QuickJS context
|
|
5
|
+
*
|
|
6
|
+
* CryptoKey is an opaque type - the actual key material stays on the host.
|
|
7
|
+
* The QuickJS instance only holds metadata and an instanceId that maps
|
|
8
|
+
* to the host-side CryptoKey.
|
|
9
|
+
*/
|
|
10
|
+
export declare function createCryptoKeyClass(context: QuickJSContext, stateMap: StateMap): QuickJSHandle;
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QuickJS Global Type Definitions for @ricsam/quickjs-crypto
|
|
3
|
+
*
|
|
4
|
+
* These types define the globals injected by setupCrypto() into a QuickJS context.
|
|
5
|
+
* Use these types to typecheck user code that will run inside QuickJS.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // Generate random bytes
|
|
9
|
+
* const arr = new Uint8Array(16);
|
|
10
|
+
* crypto.getRandomValues(arr);
|
|
11
|
+
*
|
|
12
|
+
* // Generate UUID
|
|
13
|
+
* const uuid = crypto.randomUUID();
|
|
14
|
+
*
|
|
15
|
+
* // Use SubtleCrypto
|
|
16
|
+
* const key = await crypto.subtle.generateKey(
|
|
17
|
+
* { name: "AES-GCM", length: 256 },
|
|
18
|
+
* true,
|
|
19
|
+
* ["encrypt", "decrypt"]
|
|
20
|
+
* );
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
export {};
|
|
24
|
+
|
|
25
|
+
declare global {
|
|
26
|
+
/**
|
|
27
|
+
* CryptoKey represents a cryptographic key.
|
|
28
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey
|
|
29
|
+
*/
|
|
30
|
+
interface CryptoKey {
|
|
31
|
+
/**
|
|
32
|
+
* The type of key: "public", "private", or "secret".
|
|
33
|
+
*/
|
|
34
|
+
readonly type: "public" | "private" | "secret";
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Whether the key can be exported.
|
|
38
|
+
*/
|
|
39
|
+
readonly extractable: boolean;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The algorithm used by this key.
|
|
43
|
+
*/
|
|
44
|
+
readonly algorithm: KeyAlgorithm;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The usages allowed for this key.
|
|
48
|
+
*/
|
|
49
|
+
readonly usages: ReadonlyArray<KeyUsage>;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* CryptoKey constructor (keys cannot be constructed directly).
|
|
54
|
+
*/
|
|
55
|
+
const CryptoKey: {
|
|
56
|
+
prototype: CryptoKey;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* SubtleCrypto interface for cryptographic operations.
|
|
61
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
|
|
62
|
+
*/
|
|
63
|
+
interface SubtleCrypto {
|
|
64
|
+
/**
|
|
65
|
+
* Generate a digest (hash) of the given data.
|
|
66
|
+
*
|
|
67
|
+
* @param algorithm - Hash algorithm (e.g., "SHA-256", "SHA-384", "SHA-512")
|
|
68
|
+
* @param data - Data to hash
|
|
69
|
+
* @returns Promise resolving to the hash as ArrayBuffer
|
|
70
|
+
*/
|
|
71
|
+
digest(
|
|
72
|
+
algorithm: AlgorithmIdentifier,
|
|
73
|
+
data: BufferSource
|
|
74
|
+
): Promise<ArrayBuffer>;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Generate a new cryptographic key or key pair.
|
|
78
|
+
*
|
|
79
|
+
* @param algorithm - Key generation algorithm
|
|
80
|
+
* @param extractable - Whether the key can be exported
|
|
81
|
+
* @param keyUsages - Allowed key usages
|
|
82
|
+
* @returns Promise resolving to a CryptoKey or CryptoKeyPair
|
|
83
|
+
*/
|
|
84
|
+
generateKey(
|
|
85
|
+
algorithm: RsaHashedKeyGenParams | EcKeyGenParams | AesKeyGenParams | HmacKeyGenParams,
|
|
86
|
+
extractable: boolean,
|
|
87
|
+
keyUsages: KeyUsage[]
|
|
88
|
+
): Promise<CryptoKey | CryptoKeyPair>;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Sign data using a private key.
|
|
92
|
+
*
|
|
93
|
+
* @param algorithm - Signing algorithm
|
|
94
|
+
* @param key - Private key to sign with
|
|
95
|
+
* @param data - Data to sign
|
|
96
|
+
* @returns Promise resolving to the signature as ArrayBuffer
|
|
97
|
+
*/
|
|
98
|
+
sign(
|
|
99
|
+
algorithm: AlgorithmIdentifier,
|
|
100
|
+
key: CryptoKey,
|
|
101
|
+
data: BufferSource
|
|
102
|
+
): Promise<ArrayBuffer>;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Verify a signature.
|
|
106
|
+
*
|
|
107
|
+
* @param algorithm - Signing algorithm
|
|
108
|
+
* @param key - Public key to verify with
|
|
109
|
+
* @param signature - Signature to verify
|
|
110
|
+
* @param data - Data that was signed
|
|
111
|
+
* @returns Promise resolving to true if valid, false otherwise
|
|
112
|
+
*/
|
|
113
|
+
verify(
|
|
114
|
+
algorithm: AlgorithmIdentifier,
|
|
115
|
+
key: CryptoKey,
|
|
116
|
+
signature: BufferSource,
|
|
117
|
+
data: BufferSource
|
|
118
|
+
): Promise<boolean>;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Encrypt data.
|
|
122
|
+
*
|
|
123
|
+
* @param algorithm - Encryption algorithm
|
|
124
|
+
* @param key - Encryption key
|
|
125
|
+
* @param data - Data to encrypt
|
|
126
|
+
* @returns Promise resolving to encrypted data as ArrayBuffer
|
|
127
|
+
*/
|
|
128
|
+
encrypt(
|
|
129
|
+
algorithm: AlgorithmIdentifier,
|
|
130
|
+
key: CryptoKey,
|
|
131
|
+
data: BufferSource
|
|
132
|
+
): Promise<ArrayBuffer>;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Decrypt data.
|
|
136
|
+
*
|
|
137
|
+
* @param algorithm - Decryption algorithm
|
|
138
|
+
* @param key - Decryption key
|
|
139
|
+
* @param data - Data to decrypt
|
|
140
|
+
* @returns Promise resolving to decrypted data as ArrayBuffer
|
|
141
|
+
*/
|
|
142
|
+
decrypt(
|
|
143
|
+
algorithm: AlgorithmIdentifier,
|
|
144
|
+
key: CryptoKey,
|
|
145
|
+
data: BufferSource
|
|
146
|
+
): Promise<ArrayBuffer>;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Import a key from external data.
|
|
150
|
+
*
|
|
151
|
+
* @param format - Key format ("raw", "pkcs8", "spki", "jwk")
|
|
152
|
+
* @param keyData - Key data
|
|
153
|
+
* @param algorithm - Key algorithm
|
|
154
|
+
* @param extractable - Whether the key can be exported
|
|
155
|
+
* @param keyUsages - Allowed key usages
|
|
156
|
+
* @returns Promise resolving to a CryptoKey
|
|
157
|
+
*/
|
|
158
|
+
importKey(
|
|
159
|
+
format: "raw" | "pkcs8" | "spki" | "jwk",
|
|
160
|
+
keyData: BufferSource | JsonWebKey,
|
|
161
|
+
algorithm: AlgorithmIdentifier,
|
|
162
|
+
extractable: boolean,
|
|
163
|
+
keyUsages: KeyUsage[]
|
|
164
|
+
): Promise<CryptoKey>;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Export a key.
|
|
168
|
+
*
|
|
169
|
+
* @param format - Export format ("raw", "pkcs8", "spki", "jwk")
|
|
170
|
+
* @param key - Key to export
|
|
171
|
+
* @returns Promise resolving to ArrayBuffer or JsonWebKey
|
|
172
|
+
*/
|
|
173
|
+
exportKey(
|
|
174
|
+
format: "raw" | "pkcs8" | "spki" | "jwk",
|
|
175
|
+
key: CryptoKey
|
|
176
|
+
): Promise<ArrayBuffer | JsonWebKey>;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Derive bits from a key.
|
|
180
|
+
*
|
|
181
|
+
* @param algorithm - Derivation algorithm
|
|
182
|
+
* @param baseKey - Base key for derivation
|
|
183
|
+
* @param length - Number of bits to derive
|
|
184
|
+
* @returns Promise resolving to derived bits as ArrayBuffer
|
|
185
|
+
*/
|
|
186
|
+
deriveBits(
|
|
187
|
+
algorithm: AlgorithmIdentifier,
|
|
188
|
+
baseKey: CryptoKey,
|
|
189
|
+
length: number
|
|
190
|
+
): Promise<ArrayBuffer>;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Derive a new key from a base key.
|
|
194
|
+
*
|
|
195
|
+
* @param algorithm - Derivation algorithm
|
|
196
|
+
* @param baseKey - Base key for derivation
|
|
197
|
+
* @param derivedKeyType - Type of key to derive
|
|
198
|
+
* @param extractable - Whether the derived key can be exported
|
|
199
|
+
* @param keyUsages - Allowed usages for derived key
|
|
200
|
+
* @returns Promise resolving to a CryptoKey
|
|
201
|
+
*/
|
|
202
|
+
deriveKey(
|
|
203
|
+
algorithm: AlgorithmIdentifier,
|
|
204
|
+
baseKey: CryptoKey,
|
|
205
|
+
derivedKeyType: AlgorithmIdentifier,
|
|
206
|
+
extractable: boolean,
|
|
207
|
+
keyUsages: KeyUsage[]
|
|
208
|
+
): Promise<CryptoKey>;
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Wrap a key for secure export.
|
|
212
|
+
*
|
|
213
|
+
* @param format - Key format
|
|
214
|
+
* @param key - Key to wrap
|
|
215
|
+
* @param wrappingKey - Key to wrap with
|
|
216
|
+
* @param wrapAlgorithm - Wrapping algorithm
|
|
217
|
+
* @returns Promise resolving to wrapped key as ArrayBuffer
|
|
218
|
+
*/
|
|
219
|
+
wrapKey(
|
|
220
|
+
format: "raw" | "pkcs8" | "spki" | "jwk",
|
|
221
|
+
key: CryptoKey,
|
|
222
|
+
wrappingKey: CryptoKey,
|
|
223
|
+
wrapAlgorithm: AlgorithmIdentifier
|
|
224
|
+
): Promise<ArrayBuffer>;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Unwrap a wrapped key.
|
|
228
|
+
*
|
|
229
|
+
* @param format - Key format
|
|
230
|
+
* @param wrappedKey - Wrapped key data
|
|
231
|
+
* @param unwrappingKey - Key to unwrap with
|
|
232
|
+
* @param unwrapAlgorithm - Unwrapping algorithm
|
|
233
|
+
* @param unwrappedKeyAlgorithm - Algorithm for the unwrapped key
|
|
234
|
+
* @param extractable - Whether the unwrapped key can be exported
|
|
235
|
+
* @param keyUsages - Allowed usages for unwrapped key
|
|
236
|
+
* @returns Promise resolving to a CryptoKey
|
|
237
|
+
*/
|
|
238
|
+
unwrapKey(
|
|
239
|
+
format: "raw" | "pkcs8" | "spki" | "jwk",
|
|
240
|
+
wrappedKey: BufferSource,
|
|
241
|
+
unwrappingKey: CryptoKey,
|
|
242
|
+
unwrapAlgorithm: AlgorithmIdentifier,
|
|
243
|
+
unwrappedKeyAlgorithm: AlgorithmIdentifier,
|
|
244
|
+
extractable: boolean,
|
|
245
|
+
keyUsages: KeyUsage[]
|
|
246
|
+
): Promise<CryptoKey>;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Crypto interface providing cryptographic functionality.
|
|
251
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Crypto
|
|
252
|
+
*/
|
|
253
|
+
interface Crypto {
|
|
254
|
+
/**
|
|
255
|
+
* SubtleCrypto interface for cryptographic operations.
|
|
256
|
+
*/
|
|
257
|
+
readonly subtle: SubtleCrypto;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Fill a TypedArray with cryptographically random values.
|
|
261
|
+
*
|
|
262
|
+
* @param array - TypedArray to fill (max 65536 bytes)
|
|
263
|
+
* @returns The same array, filled with random values
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* const arr = new Uint8Array(16);
|
|
267
|
+
* crypto.getRandomValues(arr);
|
|
268
|
+
*/
|
|
269
|
+
getRandomValues<T extends ArrayBufferView | null>(array: T): T;
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Generate a random UUID v4.
|
|
273
|
+
*
|
|
274
|
+
* @returns A random UUID string
|
|
275
|
+
*
|
|
276
|
+
* @example
|
|
277
|
+
* const uuid = crypto.randomUUID();
|
|
278
|
+
* // "550e8400-e29b-41d4-a716-446655440000"
|
|
279
|
+
*/
|
|
280
|
+
randomUUID(): string;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Crypto object providing cryptographic functionality.
|
|
285
|
+
*/
|
|
286
|
+
const crypto: Crypto;
|
|
287
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
|
|
2
|
+
/**
|
|
3
|
+
* Create the getRandomValues function for the crypto global
|
|
4
|
+
*
|
|
5
|
+
* getRandomValues fills a TypedArray with cryptographically random values
|
|
6
|
+
* and returns the same array (modified in-place)
|
|
7
|
+
*/
|
|
8
|
+
export declare function createGetRandomValuesFunction(context: QuickJSContext): QuickJSHandle;
|
|
9
|
+
/**
|
|
10
|
+
* Create the randomUUID function for the crypto global
|
|
11
|
+
*
|
|
12
|
+
* randomUUID returns a string containing a randomly generated UUID v4
|
|
13
|
+
*/
|
|
14
|
+
export declare function createRandomUUIDFunction(context: QuickJSContext): QuickJSHandle;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { QuickJSContext } from "quickjs-emscripten";
|
|
2
|
+
import type { SetupCryptoOptions, CryptoHandle } from "./types.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Setup crypto globals in a QuickJS context
|
|
5
|
+
*
|
|
6
|
+
* Provides: crypto.subtle (SubtleCrypto), crypto.getRandomValues, crypto.randomUUID, CryptoKey
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const handle = setupCrypto(context);
|
|
11
|
+
*
|
|
12
|
+
* context.evalCode(`
|
|
13
|
+
* // Generate a random UUID
|
|
14
|
+
* const uuid = crypto.randomUUID();
|
|
15
|
+
*
|
|
16
|
+
* // Generate random bytes
|
|
17
|
+
* const arr = new Uint8Array(16);
|
|
18
|
+
* crypto.getRandomValues(arr);
|
|
19
|
+
*
|
|
20
|
+
* // Use SubtleCrypto for encryption
|
|
21
|
+
* const key = await crypto.subtle.generateKey(
|
|
22
|
+
* { name: "AES-GCM", length: 256 },
|
|
23
|
+
* true,
|
|
24
|
+
* ["encrypt", "decrypt"]
|
|
25
|
+
* );
|
|
26
|
+
*
|
|
27
|
+
* const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
28
|
+
* const data = new TextEncoder().encode("secret message");
|
|
29
|
+
* const encrypted = await crypto.subtle.encrypt(
|
|
30
|
+
* { name: "AES-GCM", iv },
|
|
31
|
+
* key,
|
|
32
|
+
* data
|
|
33
|
+
* );
|
|
34
|
+
* `);
|
|
35
|
+
*
|
|
36
|
+
* handle.dispose();
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @param context - QuickJS context
|
|
40
|
+
* @param options - Setup options
|
|
41
|
+
* @returns CryptoHandle for cleanup
|
|
42
|
+
*/
|
|
43
|
+
export declare function setupCrypto(context: QuickJSContext, options?: SetupCryptoOptions): CryptoHandle;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
|
|
2
|
+
/**
|
|
3
|
+
* Helper to create a CryptoKey instance in QuickJS from a host CryptoKey
|
|
4
|
+
*
|
|
5
|
+
* This registers the host key in our state management and creates
|
|
6
|
+
* a QuickJS CryptoKey object that references it via __instanceId__
|
|
7
|
+
*/
|
|
8
|
+
export declare function createCryptoKeyInstance(context: QuickJSContext, hostKey: globalThis.CryptoKey): QuickJSHandle;
|
|
9
|
+
/**
|
|
10
|
+
* Create the SubtleCrypto object with all methods
|
|
11
|
+
*/
|
|
12
|
+
export declare function createSubtleCryptoObject(context: QuickJSContext): QuickJSHandle;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { StateMap, CoreHandle } from "@ricsam/quickjs-core";
|
|
2
|
+
export type { StateMap, CoreHandle };
|
|
3
|
+
/**
|
|
4
|
+
* Key usage types as defined by Web Crypto API
|
|
5
|
+
*/
|
|
6
|
+
export type KeyUsage = "encrypt" | "decrypt" | "sign" | "verify" | "deriveKey" | "deriveBits" | "wrapKey" | "unwrapKey";
|
|
7
|
+
/**
|
|
8
|
+
* Key type
|
|
9
|
+
*/
|
|
10
|
+
export type KeyType = "public" | "private" | "secret";
|
|
11
|
+
/**
|
|
12
|
+
* Internal state for CryptoKey instances
|
|
13
|
+
* The actual CryptoKey stays on the host side
|
|
14
|
+
*/
|
|
15
|
+
export interface CryptoKeyState {
|
|
16
|
+
/** Reference to host crypto key (actual CryptoKey from host) */
|
|
17
|
+
hostKey: globalThis.CryptoKey;
|
|
18
|
+
/** Key type: public, private, or secret */
|
|
19
|
+
type: KeyType;
|
|
20
|
+
/** Whether the key can be exported */
|
|
21
|
+
extractable: boolean;
|
|
22
|
+
/** Algorithm information */
|
|
23
|
+
algorithm: KeyAlgorithm;
|
|
24
|
+
/** Allowed usages for this key */
|
|
25
|
+
usages: KeyUsage[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Options for setupCrypto
|
|
29
|
+
*/
|
|
30
|
+
export interface SetupCryptoOptions {
|
|
31
|
+
/** Shared state map for instance tracking */
|
|
32
|
+
stateMap?: StateMap;
|
|
33
|
+
/** Core handle from setupCore */
|
|
34
|
+
coreHandle?: CoreHandle;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Handle returned from setupCrypto
|
|
38
|
+
*/
|
|
39
|
+
export interface CryptoHandle {
|
|
40
|
+
/** Shared state map */
|
|
41
|
+
readonly stateMap: StateMap;
|
|
42
|
+
/** Dispose and cleanup */
|
|
43
|
+
dispose(): void;
|
|
44
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,58 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ricsam/quickjs-crypto",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
3
|
+
"version": "0.2.13",
|
|
4
|
+
"main": "./dist/cjs/index.cjs",
|
|
5
|
+
"types": "./dist/types/index.d.ts",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/types/index.d.ts",
|
|
9
|
+
"require": "./dist/cjs/index.cjs",
|
|
10
|
+
"import": "./dist/mjs/index.mjs"
|
|
11
|
+
},
|
|
12
|
+
"./quickjs": {
|
|
13
|
+
"types": "./dist/types/quickjs.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "bun build ./src/index.ts --outdir ./dist --target bun",
|
|
18
|
+
"test": "bun test",
|
|
19
|
+
"typecheck": "tsc --noEmit"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@ricsam/quickjs-core": "^0.2.13",
|
|
23
|
+
"quickjs-emscripten": "^0.31.0"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"quickjs-emscripten": "^0.31.0"
|
|
27
|
+
},
|
|
28
|
+
"author": "Richard Samuelsson",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/ricsam/richie-qjs.git"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/ricsam/richie-qjs/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/ricsam/richie-qjs#readme",
|
|
5
38
|
"keywords": [
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
39
|
+
"quickjs",
|
|
40
|
+
"sandbox",
|
|
41
|
+
"javascript",
|
|
42
|
+
"runtime",
|
|
43
|
+
"fetch",
|
|
44
|
+
"filesystem",
|
|
45
|
+
"streams",
|
|
46
|
+
"wasm",
|
|
47
|
+
"emscripten"
|
|
48
|
+
],
|
|
49
|
+
"description": "Web Crypto API implementation for QuickJS runtime",
|
|
50
|
+
"module": "./dist/mjs/index.mjs",
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
},
|
|
54
|
+
"files": [
|
|
55
|
+
"dist",
|
|
56
|
+
"README.md"
|
|
9
57
|
]
|
|
10
|
-
}
|
|
58
|
+
}
|
package/README.md
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# @ricsam/quickjs-crypto
|
|
2
|
-
|
|
3
|
-
## ⚠️ IMPORTANT NOTICE ⚠️
|
|
4
|
-
|
|
5
|
-
**This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
|
|
6
|
-
|
|
7
|
-
This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
|
|
8
|
-
|
|
9
|
-
## Purpose
|
|
10
|
-
|
|
11
|
-
This package exists to:
|
|
12
|
-
1. Configure OIDC trusted publishing for the package name `@ricsam/quickjs-crypto`
|
|
13
|
-
2. Enable secure, token-less publishing from CI/CD workflows
|
|
14
|
-
3. Establish provenance for packages published under this name
|
|
15
|
-
|
|
16
|
-
## What is OIDC Trusted Publishing?
|
|
17
|
-
|
|
18
|
-
OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
|
|
19
|
-
|
|
20
|
-
## Setup Instructions
|
|
21
|
-
|
|
22
|
-
To properly configure OIDC trusted publishing for this package:
|
|
23
|
-
|
|
24
|
-
1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
|
|
25
|
-
2. Configure the trusted publisher (e.g., GitHub Actions)
|
|
26
|
-
3. Specify the repository and workflow that should be allowed to publish
|
|
27
|
-
4. Use the configured workflow to publish your actual package
|
|
28
|
-
|
|
29
|
-
## DO NOT USE THIS PACKAGE
|
|
30
|
-
|
|
31
|
-
This package is a placeholder for OIDC configuration only. It:
|
|
32
|
-
- Contains no executable code
|
|
33
|
-
- Provides no functionality
|
|
34
|
-
- Should not be installed as a dependency
|
|
35
|
-
- Exists only for administrative purposes
|
|
36
|
-
|
|
37
|
-
## More Information
|
|
38
|
-
|
|
39
|
-
For more details about npm's trusted publishing feature, see:
|
|
40
|
-
- [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
|
|
41
|
-
- [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
**Maintained for OIDC setup purposes only**
|