@sebastienrousseau/crypto-vue 0.0.7

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/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ This project is dual-licensed under either of:
2
+
3
+ * Apache License, Version 2.0 — see LICENSE-APACHE
4
+ * MIT license — see LICENSE-MIT
5
+
6
+ at your option.
7
+
8
+ SPDX-License-Identifier: Apache-2.0 OR MIT
package/README.md ADDED
@@ -0,0 +1,271 @@
1
+ <!-- SPDX-License-Identifier: Apache-2.0 OR MIT -->
2
+
3
+ <p align="center">
4
+ <img src="https://raw.githubusercontent.com/sebastienrousseau/crypto-service/main/assets/crypto-vue-logo.svg" alt="crypto-vue logo" width="360" />
5
+ </p>
6
+
7
+ <h1 align="center">@sebastienrousseau/crypto-vue</h1>
8
+
9
+ <p align="center">
10
+ Vue 3 composables for client-side cryptography — key generation, encryption, signing, and hashing with reactive state.
11
+ </p>
12
+
13
+ <p align="center">
14
+ <a href="https://github.com/sebastienrousseau/crypto-service/actions"><img src="https://img.shields.io/github/actions/workflow/status/sebastienrousseau/crypto-service/ci.yml?branch=main&style=for-the-badge&logo=github" alt="Build" /></a>
15
+ <a href="https://coveralls.io/github/sebastienrousseau/crypto-service?branch=main"><img src="https://img.shields.io/coveralls/github/sebastienrousseau/crypto-service?branch=main&style=for-the-badge" alt="Coverage" /></a>
16
+ <a href="https://www.npmjs.com/package/@sebastienrousseau/crypto-vue"><img src="https://img.shields.io/npm/v/@sebastienrousseau/crypto-vue.svg?style=for-the-badge&color=f14041&logo=npm" alt="Registry" /></a>
17
+ <a href="https://sebastienrousseau.github.io/crypto-service/"><img src="https://img.shields.io/badge/docs-TypeDoc-blue.svg?style=for-the-badge&labelColor=555555&logo=typescript" alt="Docs" /></a>
18
+ <a href="https://scorecard.dev/viewer/?uri=github.com/sebastienrousseau/crypto-service" title="ossf-scorecard"><img src="https://img.shields.io/badge/OpenSSF-Scorecard-blue?style=for-the-badge&logo=openssf" alt="OpenSSF Scorecard" /></a>
19
+ <a href="https://github.com/sebastienrousseau/crypto-service/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0%20OR%20MIT-blue.svg?style=for-the-badge" alt="License: Apache-2.0 OR MIT" /></a>
20
+ <a href="https://github.com/sebastienrousseau/crypto-service/blob/main/docs/POLICIES.md"><img src="https://img.shields.io/badge/Node.js-%3E%3D22-93450a.svg?style=for-the-badge&logo=node.js" alt="Node.js 22 or newer" /></a>
21
+ <a href="https://vuejs.org/"><img src="https://img.shields.io/badge/vue-%3E%3D3.3-42b883.svg?style=for-the-badge&logo=vue.js" alt="Vue >= 3.3" /></a>
22
+ </p>
23
+
24
+ ---
25
+
26
+ ## Contents
27
+
28
+ **Getting started**
29
+
30
+ - [Install](#install) — installation via pnpm, npm, or yarn
31
+ - [Requirements](#requirements) — runtime floor and environment prerequisites
32
+ - [Quick Start](#quick-start) — minimal working usage sample
33
+
34
+ **The Crypto Service ecosystem**
35
+
36
+ - [The Crypto Service ecosystem](#the-crypto-service-ecosystem) — full 14-package suite overview
37
+
38
+ **Package reference**
39
+
40
+ - [Reference & Usage](#overview) — features, configuration, and capabilities
41
+ - [Examples](#examples) — runnable sample code
42
+
43
+ **Operational**
44
+
45
+ - [Development](#development) — build, lint, format, and test targets
46
+ - [Security](#security) — vulnerability disclosure and cryptographic invariants
47
+ - [Documentation](#documentation) — TypeDoc API docs and ecosystem guides
48
+ - [Stability guarantees](#stability-guarantees) — SemVer axis and release policy
49
+ - [License](#license)
50
+
51
+ ---
52
+
53
+ ## Install
54
+
55
+ ```bash
56
+ pnpm add @sebastienrousseau/crypto-vue
57
+ # or
58
+ npm install @sebastienrousseau/crypto-vue
59
+ # or
60
+ yarn add @sebastienrousseau/crypto-vue
61
+ ```
62
+
63
+ <p align="right"><a href="#contents">Back to Top</a></p>
64
+
65
+ ---
66
+
67
+ ## Requirements
68
+
69
+ - **Node.js**: `^22.0.0` or `>=24.0.0` (active and maintenance LTS releases)
70
+ - **Package Manager**: `pnpm >=9` (recommended) or `npm >=10`
71
+ - **TypeScript**: `>=5.0` (when compiling with TypeScript)
72
+
73
+ <p align="right"><a href="#contents">Back to Top</a></p>
74
+
75
+ ---
76
+
77
+ ## Quick Start
78
+
79
+ ```vue
80
+ <script setup lang="ts">
81
+ import { useKeypair } from "@sebastienrousseau/crypto-vue";
82
+
83
+ const { publicKey, privateKey, generate, isGenerating } = useKeypair();
84
+ </script>
85
+
86
+ <template>
87
+ <button @click="generate('ed25519')" :disabled="isGenerating">
88
+ Generate Key Pair
89
+ </button>
90
+ <pre v-if="publicKey">{{ publicKey }}</pre>
91
+ </template>
92
+ ```
93
+
94
+ <p align="right"><a href="#contents">Back to Top</a></p>
95
+
96
+ ---
97
+
98
+ ## The Crypto Service ecosystem
99
+
100
+ Crypto Service provides a complete cryptography stack across 14 specialized packages:
101
+
102
+ | Package | Role | Description |
103
+ | :-------------------------------------------------------------------- | :------------------ | :------------------------------------------------------------------------------------------------------------------------------------- |
104
+ | [`@sebastienrousseau/crypto-api`](../crypto-api) | API Schemas | Shared TypeScript types and utilities for the Crypto Service Suite, defining the canonical API surface. |
105
+ | [`@sebastienrousseau/crypto-cli`](../crypto-cli) | Terminal CLI | An interactive command-line interface for cryptographic operations, supporting both legacy OpenPGP and modern post-quantum algorithms. |
106
+ | [`@sebastienrousseau/crypto-edge`](../crypto-edge) | Edge Runtime | Edge-runtime cryptographic operations using the Web Crypto API, optimized for Cloudflare Workers, Vercel Edge, and Deno. |
107
+ | [`@sebastienrousseau/crypto-kms`](../crypto-kms) | Cloud KMS | Unified Key Management Service interface for AWS KMS, GCP Cloud KMS, Azure Key Vault, and HashiCorp Vault. |
108
+ | [`@sebastienrousseau/crypto-lib`](../crypto-lib) | Core Library | A modern cryptographic library for TypeScript, with post-quantum support, zero unsafe dependencies, and 100% test coverage. |
109
+ | [`@sebastienrousseau/crypto-middleware`](../crypto-middleware) | Middleware | Framework-agnostic cryptographic middleware for Express, Fastify, and Koa applications. |
110
+ | [`@sebastienrousseau/crypto-prisma`](../crypto-prisma) | ORM Adapter | Transparent field-level encryption extension for Prisma Client, using XChaCha20-Poly1305. |
111
+ | [`@sebastienrousseau/crypto-react`](../crypto-react) | React Hooks | React hooks and context provider for client-side cryptographic operations with zero boilerplate. |
112
+ | [`@sebastienrousseau/crypto-sdk`](../crypto-sdk) | Client SDK | A zero-dependency, typed HTTP client for the Crypto Service REST API, with full post-quantum support. |
113
+ | [`@sebastienrousseau/crypto-server`](../crypto-server) | HTTP API | A hardened Fastify REST API for cryptographic operations, with rate limiting, OpenAPI schemas, and post-quantum endpoints. |
114
+ | [`@sebastienrousseau/crypto-testing`](../crypto-testing) | Test Support | Deterministic keys, fast mocks, and test fixtures for crypto-lib |
115
+ | [`@sebastienrousseau/crypto-typeorm`](../crypto-typeorm) | ORM Adapter | TypeORM column-level encryption with a single decorator, powered by crypto-lib. |
116
+ | **[`@sebastienrousseau/crypto-vue`](../crypto-vue)** _(this package)_ | **Vue Composables** | **Vue 3 composables for client-side cryptography** |
117
+ | [`@sebastienrousseau/crypto-wasm`](../crypto-wasm) | Acceleration | WebAssembly performance accelerator for crypto-lib |
118
+
119
+ <p align="right"><a href="#contents">Back to Top</a></p>
120
+
121
+ ---
122
+
123
+ ## Overview
124
+
125
+ crypto-vue provides Vue 3 composables for client-side cryptographic
126
+ operations. It wraps `@sebastienrousseau/crypto-lib` in a reactive
127
+ API with composables for key generation, symmetric encryption,
128
+ hashing, and digital signatures. An optional `CryptoPlugin` supplies
129
+ global configuration (default key, server URL, API key) via Vue's
130
+ provide/inject system.
131
+
132
+ <p align="right"><a href="#contents">Back to Top</a></p>
133
+
134
+ ## CryptoPlugin
135
+
136
+ An optional Vue plugin that provides global configuration to all
137
+ composables via `inject`/`provide`.
138
+
139
+ ```ts
140
+ // main.ts
141
+ import { createApp } from "vue";
142
+ import { CryptoPlugin } from "@sebastienrousseau/crypto-vue";
143
+ import App from "./App.vue";
144
+
145
+ const app = createApp(App);
146
+
147
+ app.use(CryptoPlugin, {
148
+ defaultKey: "your-256-bit-hex-key",
149
+ serverUrl: "https://api.example.com",
150
+ apiKey: "your-api-key",
151
+ });
152
+
153
+ app.mount("#app");
154
+ ```
155
+
156
+ | Option | Type | Description |
157
+ | :----------- | :------- | :------------------------------------------ |
158
+ | `defaultKey` | `string` | Default encryption key (256-bit hex string) |
159
+ | `serverUrl` | `string` | Base URL for the Crypto Service REST API |
160
+ | `apiKey` | `string` | API key for authenticated server requests |
161
+
162
+ <p align="right"><a href="#contents">Back to Top</a></p>
163
+
164
+ ## Composables Reference
165
+
166
+ ### `useKeypair()`
167
+
168
+ Reactive key pair generation for any supported algorithm.
169
+
170
+ **Supported algorithms:** `ed25519`, `x25519`, `ed448`, `x448`,
171
+ `p256`, `p384`, `ml-kem-512`, `ml-kem-768`, `ml-kem-1024`,
172
+ `ml-dsa-44`, `ml-dsa-65`, `ml-dsa-87`
173
+
174
+ ### `useEncrypt()`
175
+
176
+ Symmetric encryption and decryption using XChaCha20-Poly1305
177
+ (secretbox).
178
+
179
+ ### `useHash()`
180
+
181
+ Cryptographic hashing with multiple algorithms.
182
+
183
+ **Supported algorithms:** `sha256`, `sha384`, `sha512`, `sha3-256`,
184
+ `sha3-512`, `blake2b`, `blake3`
185
+
186
+ ### `useSignature()`
187
+
188
+ Digital signature creation and verification.
189
+
190
+ **Supported algorithms:** `ed25519`, `ed448`, `ecdsa-p256`,
191
+ `ecdsa-p384`, `schnorr`, `ml-dsa-44`, `ml-dsa-65`, `ml-dsa-87`
192
+
193
+ <p align="right"><a href="#contents">Back to Top</a></p>
194
+
195
+ ## Examples
196
+
197
+ All examples are self-contained TypeScript files in the `examples/`
198
+ directory. Run any example with:
199
+
200
+ ```bash
201
+ npx ts-node examples/<name>.ts
202
+ ```
203
+
204
+ | Category | Example | Purpose |
205
+ | :------------- | :-------------------------------- | :-------------------------------------------- |
206
+ | Plugin | [plugin.ts](examples/plugin.ts) | CryptoPlugin setup and injection |
207
+ | Key Generation | [keygen.ts](examples/keygen.ts) | Generate Ed25519 and ML-DSA-65 key pairs |
208
+ | Encryption | [encrypt.ts](examples/encrypt.ts) | Secretbox encrypt and decrypt round-trip |
209
+ | Hashing | [hash.ts](examples/hash.ts) | SHA-256, SHA3-256, and BLAKE3 hashing |
210
+ | Signing | [sign.ts](examples/sign.ts) | Ed25519 sign and verify with tamper detection |
211
+
212
+ <p align="right"><a href="#contents">Back to Top</a></p>
213
+
214
+ <p align="right"><a href="#contents">Back to Top</a></p>
215
+
216
+ ---
217
+
218
+ ## Development
219
+
220
+ ```bash
221
+ pnpm --filter @sebastienrousseau/crypto-vue run build
222
+ pnpm --filter @sebastienrousseau/crypto-vue run test
223
+ pnpm --filter @sebastienrousseau/crypto-vue run lint
224
+ pnpm --filter @sebastienrousseau/crypto-vue run format
225
+ ```
226
+
227
+ All 18 packages in the Crypto Service workspace maintain a **100% coverage floor** across statements, branches, functions, and lines.
228
+
229
+ <p align="right"><a href="#contents">Back to Top</a></p>
230
+
231
+ ---
232
+
233
+ ## Security
234
+
235
+ Report vulnerabilities privately via [GitHub Security Advisories](https://github.com/sebastienrousseau/crypto-service/security/advisories) or according to [`SECURITY.md`](../../SECURITY.md). Never report security issues publicly.
236
+
237
+ Cryptographic operations use the `@noble/*` libraries, Node.js `crypto` and OpenPGP.js. `@noble/post-quantum` has not been independently audited and does not guarantee constant-time execution, and no module in this suite is FIPS 140-3 validated. Key zeroization is limited: JavaScript strings and garbage-collected buffers cannot be reliably wiped. See [`SECURITY.md`](../../SECURITY.md).
238
+
239
+ <p align="right"><a href="#contents">Back to Top</a></p>
240
+
241
+ ---
242
+
243
+ ## Documentation
244
+
245
+ - [Full Suite Documentation](https://sebastienrousseau.github.io/crypto-service/)
246
+ - [API Reference (TypeDoc)](https://sebastienrousseau.github.io/crypto-service/)
247
+ - [Developer Guide](../../DEVELOPMENT.md)
248
+ - [Security Policy](../../SECURITY.md)
249
+ - [Architecture & Design](../../ARCHITECTURE.md)
250
+
251
+ <p align="right"><a href="#contents">Back to Top</a></p>
252
+
253
+ ---
254
+
255
+ ## Stability guarantees
256
+
257
+ Versions advance strictly one step at a time on the `0.0.x` line (`v0.0.1` → `v0.0.2` → `v0.0.3` ... → `v0.0.999` → `v0.1.0`). Work for every release iteration begins on a dedicated `feat/v<version>` branch.
258
+
259
+ All 18 packages in the workspace move in lockstep. Public API signatures, cipher output formats, and serialization schemas are strictly versioned. Breaking changes to serialized formats or algorithm defaults are considered major breaking changes. Minimum toolchain upgrades (e.g. Node.js LTS floor) are governed by [POLICIES.md](../../docs/POLICIES.md).
260
+
261
+ <p align="right"><a href="#contents">Back to Top</a></p>
262
+
263
+ ---
264
+
265
+ ## License
266
+
267
+ Dual-licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) or [MIT](https://opensource.org/licenses/MIT), at your option.
268
+
269
+ Copyright (c) 2022-2026 Sebastien Rousseau and The Crypto Service Suite contributors.
270
+
271
+ <p align="right"><a href="#contents">Back to Top</a></p>
@@ -0,0 +1,13 @@
1
+ import { type Ref, type DeepReadonly } from "vue";
2
+ export interface UseEncryptReturn {
3
+ ciphertext: DeepReadonly<Ref<string | null>>;
4
+ plaintext: DeepReadonly<Ref<string | null>>;
5
+ isProcessing: DeepReadonly<Ref<boolean>>;
6
+ error: DeepReadonly<Ref<Error | null>>;
7
+ encrypt: (key: string, data: string | Uint8Array) => Promise<string>;
8
+ decrypt: (key: string, data: string) => Promise<Uint8Array>;
9
+ randomKey: () => string;
10
+ clear: () => void;
11
+ }
12
+ export declare function useEncrypt(): UseEncryptReturn;
13
+ //# sourceMappingURL=useEncrypt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEncrypt.d.ts","sourceRoot":"","sources":["../../src/composables/useEncrypt.ts"],"names":[],"mappings":"AAGA,OAAO,EAAyB,KAAK,GAAG,EAAE,KAAK,YAAY,EAAE,MAAM,KAAK,CAAC;AAczE,MAAM,WAAW,gBAAgB;IAE/B,UAAU,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAE7C,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAE5C,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAEzC,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;IAEvC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAErE,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAE5D,SAAS,EAAE,MAAM,MAAM,CAAC;IAExB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAkBD,wBAAgB,UAAU,IAAI,gBAAgB,CAoF7C"}
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useEncrypt = useEncrypt;
4
+ const vue_1 = require("vue");
5
+ const crypto_lib_1 = require("@sebastienrousseau/crypto-lib");
6
+ const plugin_1 = require("../plugin");
7
+ function useEncrypt() {
8
+ const opts = (0, vue_1.inject)(plugin_1.CryptoSymbol, {});
9
+ const ciphertext = (0, vue_1.ref)(null);
10
+ const plaintext = (0, vue_1.ref)(null);
11
+ const isProcessing = (0, vue_1.ref)(false);
12
+ const error = (0, vue_1.ref)(null);
13
+ function resolveKey(key) {
14
+ const resolved = key ?? opts.defaultKey;
15
+ if (!resolved) {
16
+ throw new Error("No encryption key provided and no defaultKey configured in CryptoPlugin.");
17
+ }
18
+ return resolved;
19
+ }
20
+ async function encrypt(key, data) {
21
+ isProcessing.value = true;
22
+ error.value = null;
23
+ try {
24
+ const k = resolveKey(key);
25
+ const ct = crypto_lib_1.crypto.encrypt(k, data);
26
+ ciphertext.value = ct;
27
+ return ct;
28
+ }
29
+ catch (err) {
30
+ error.value = err instanceof Error ? err : new Error(String(err));
31
+ throw error.value;
32
+ }
33
+ finally {
34
+ isProcessing.value = false;
35
+ }
36
+ }
37
+ async function decrypt(key, data) {
38
+ isProcessing.value = true;
39
+ error.value = null;
40
+ try {
41
+ const k = resolveKey(key);
42
+ const pt = crypto_lib_1.crypto.decrypt(k, data);
43
+ plaintext.value = new TextDecoder().decode(pt);
44
+ return pt;
45
+ }
46
+ catch (err) {
47
+ error.value = err instanceof Error ? err : new Error(String(err));
48
+ throw error.value;
49
+ }
50
+ finally {
51
+ isProcessing.value = false;
52
+ }
53
+ }
54
+ function randomKey() {
55
+ return crypto_lib_1.crypto.randomKey();
56
+ }
57
+ function clear() {
58
+ ciphertext.value = null;
59
+ plaintext.value = null;
60
+ error.value = null;
61
+ }
62
+ return {
63
+ ciphertext: (0, vue_1.readonly)(ciphertext),
64
+ plaintext: (0, vue_1.readonly)(plaintext),
65
+ isProcessing: (0, vue_1.readonly)(isProcessing),
66
+ error: (0, vue_1.readonly)(error),
67
+ encrypt,
68
+ decrypt,
69
+ randomKey,
70
+ clear,
71
+ };
72
+ }
73
+ //# sourceMappingURL=useEncrypt.js.map
@@ -0,0 +1,13 @@
1
+ import { type Ref, type DeepReadonly } from "vue";
2
+ import { type HashAlgorithm as _HashAlgorithm } from "@sebastienrousseau/crypto-lib";
3
+ export type HashAlgorithm = _HashAlgorithm;
4
+ export interface UseHashReturn {
5
+ digest: DeepReadonly<Ref<string | null>>;
6
+ algorithm: DeepReadonly<Ref<HashAlgorithm | null>>;
7
+ isHashing: DeepReadonly<Ref<boolean>>;
8
+ error: DeepReadonly<Ref<Error | null>>;
9
+ hash: (algo: HashAlgorithm, data: string | Uint8Array) => Promise<string>;
10
+ clear: () => void;
11
+ }
12
+ export declare function useHash(): UseHashReturn;
13
+ //# sourceMappingURL=useHash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useHash.d.ts","sourceRoot":"","sources":["../../src/composables/useHash.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,KAAK,GAAG,EAAE,KAAK,YAAY,EAAE,MAAM,KAAK,CAAC;AACjE,OAAO,EAEL,KAAK,aAAa,IAAI,cAAc,EACrC,MAAM,+BAA+B,CAAC;AAWvC,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC;AAY3C,MAAM,WAAW,aAAa;IAE5B,MAAM,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAEzC,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC,CAAC;IAEnD,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAEtC,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;IAEvC,IAAI,EAAE,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1E,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAgBD,wBAAgB,OAAO,IAAI,aAAa,CA4CvC"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useHash = useHash;
4
+ const vue_1 = require("vue");
5
+ const crypto_lib_1 = require("@sebastienrousseau/crypto-lib");
6
+ function useHash() {
7
+ const digest = (0, vue_1.ref)(null);
8
+ const algorithm = (0, vue_1.ref)(null);
9
+ const isHashing = (0, vue_1.ref)(false);
10
+ const error = (0, vue_1.ref)(null);
11
+ async function hash(algo, data) {
12
+ isHashing.value = true;
13
+ error.value = null;
14
+ try {
15
+ const result = crypto_lib_1.crypto.hash(algo, data);
16
+ digest.value = result;
17
+ algorithm.value = algo;
18
+ return result;
19
+ }
20
+ catch (err) {
21
+ error.value = err instanceof Error ? err : new Error(String(err));
22
+ throw error.value;
23
+ }
24
+ finally {
25
+ isHashing.value = false;
26
+ }
27
+ }
28
+ function clear() {
29
+ digest.value = null;
30
+ algorithm.value = null;
31
+ error.value = null;
32
+ }
33
+ return {
34
+ digest: (0, vue_1.readonly)(digest),
35
+ algorithm: (0, vue_1.readonly)(algorithm),
36
+ isHashing: (0, vue_1.readonly)(isHashing),
37
+ error: (0, vue_1.readonly)(error),
38
+ hash,
39
+ clear,
40
+ };
41
+ }
42
+ //# sourceMappingURL=useHash.js.map
@@ -0,0 +1,13 @@
1
+ import { type Ref, type DeepReadonly } from "vue";
2
+ import { type KeyAlgorithm, type GeneratedKeyPair } from "@sebastienrousseau/crypto-lib";
3
+ export interface UseKeypairReturn {
4
+ publicKey: DeepReadonly<Ref<string | null>>;
5
+ privateKey: DeepReadonly<Ref<string | null>>;
6
+ algorithm: DeepReadonly<Ref<KeyAlgorithm | null>>;
7
+ isGenerating: DeepReadonly<Ref<boolean>>;
8
+ error: DeepReadonly<Ref<Error | null>>;
9
+ generate: (algo: KeyAlgorithm) => Promise<GeneratedKeyPair>;
10
+ clear: () => void;
11
+ }
12
+ export declare function useKeypair(): UseKeypairReturn;
13
+ //# sourceMappingURL=useKeypair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useKeypair.d.ts","sourceRoot":"","sources":["../../src/composables/useKeypair.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,KAAK,GAAG,EAAE,KAAK,YAAY,EAAE,MAAM,KAAK,CAAC;AACjE,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,+BAA+B,CAAC;AAYvC,MAAM,WAAW,gBAAgB;IAE/B,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAE5C,UAAU,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAE7C,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC,CAAC;IAElD,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAEzC,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;IAEvC,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAE5D,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAaD,wBAAgB,UAAU,IAAI,gBAAgB,CA6C7C"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useKeypair = useKeypair;
4
+ const vue_1 = require("vue");
5
+ const crypto_lib_1 = require("@sebastienrousseau/crypto-lib");
6
+ function useKeypair() {
7
+ const publicKey = (0, vue_1.ref)(null);
8
+ const privateKey = (0, vue_1.ref)(null);
9
+ const algorithm = (0, vue_1.ref)(null);
10
+ const isGenerating = (0, vue_1.ref)(false);
11
+ const error = (0, vue_1.ref)(null);
12
+ async function generate(algo) {
13
+ isGenerating.value = true;
14
+ error.value = null;
15
+ try {
16
+ const keyPair = (0, crypto_lib_1.generateKeyPair)(algo);
17
+ publicKey.value = keyPair.publicKey;
18
+ privateKey.value = keyPair.privateKey;
19
+ algorithm.value = algo;
20
+ return keyPair;
21
+ }
22
+ catch (err) {
23
+ error.value = err instanceof Error ? err : new Error(String(err));
24
+ throw error.value;
25
+ }
26
+ finally {
27
+ isGenerating.value = false;
28
+ }
29
+ }
30
+ function clear() {
31
+ publicKey.value = null;
32
+ privateKey.value = null;
33
+ algorithm.value = null;
34
+ error.value = null;
35
+ }
36
+ return {
37
+ publicKey: (0, vue_1.readonly)(publicKey),
38
+ privateKey: (0, vue_1.readonly)(privateKey),
39
+ algorithm: (0, vue_1.readonly)(algorithm),
40
+ isGenerating: (0, vue_1.readonly)(isGenerating),
41
+ error: (0, vue_1.readonly)(error),
42
+ generate,
43
+ clear,
44
+ };
45
+ }
46
+ //# sourceMappingURL=useKeypair.js.map
@@ -0,0 +1,15 @@
1
+ import { type Ref, type DeepReadonly } from "vue";
2
+ import { type SignAlgorithm as _SignAlgorithm } from "@sebastienrousseau/crypto-lib";
3
+ export type SignAlgorithm = _SignAlgorithm;
4
+ export interface UseSignatureReturn {
5
+ signature: DeepReadonly<Ref<string | null>>;
6
+ isValid: DeepReadonly<Ref<boolean | null>>;
7
+ algorithm: DeepReadonly<Ref<SignAlgorithm | null>>;
8
+ isProcessing: DeepReadonly<Ref<boolean>>;
9
+ error: DeepReadonly<Ref<Error | null>>;
10
+ sign: (algo: SignAlgorithm, privateKeyHex: string, message: string | Uint8Array) => Promise<string>;
11
+ verify: (algo: SignAlgorithm, publicKeyHex: string, message: string | Uint8Array, signatureHex: string) => Promise<boolean>;
12
+ clear: () => void;
13
+ }
14
+ export declare function useSignature(): UseSignatureReturn;
15
+ //# sourceMappingURL=useSignature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSignature.d.ts","sourceRoot":"","sources":["../../src/composables/useSignature.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,KAAK,GAAG,EAAE,KAAK,YAAY,EAAE,MAAM,KAAK,CAAC;AACjE,OAAO,EAEL,KAAK,aAAa,IAAI,cAAc,EACrC,MAAM,+BAA+B,CAAC;AAWvC,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC;AAY3C,MAAM,WAAW,kBAAkB;IAEjC,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IAE5C,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC;IAE3C,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC,CAAC;IAEnD,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;IAEzC,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;IAEvC,IAAI,EAAE,CACJ,IAAI,EAAE,aAAa,EACnB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,GAAG,UAAU,KACzB,OAAO,CAAC,MAAM,CAAC,CAAC;IAErB,MAAM,EAAE,CACN,IAAI,EAAE,aAAa,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,GAAG,UAAU,EAC5B,YAAY,EAAE,MAAM,KACjB,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAiBD,wBAAgB,YAAY,IAAI,kBAAkB,CA0EjD"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useSignature = useSignature;
4
+ const vue_1 = require("vue");
5
+ const crypto_lib_1 = require("@sebastienrousseau/crypto-lib");
6
+ function useSignature() {
7
+ const signature = (0, vue_1.ref)(null);
8
+ const isValid = (0, vue_1.ref)(null);
9
+ const algorithm = (0, vue_1.ref)(null);
10
+ const isProcessing = (0, vue_1.ref)(false);
11
+ const error = (0, vue_1.ref)(null);
12
+ async function sign(algo, privateKeyHex, message) {
13
+ isProcessing.value = true;
14
+ error.value = null;
15
+ try {
16
+ const sig = crypto_lib_1.crypto.sign(algo, privateKeyHex, message);
17
+ signature.value = sig;
18
+ algorithm.value = algo;
19
+ return sig;
20
+ }
21
+ catch (err) {
22
+ error.value = err instanceof Error ? err : new Error(String(err));
23
+ throw error.value;
24
+ }
25
+ finally {
26
+ isProcessing.value = false;
27
+ }
28
+ }
29
+ async function verify(algo, publicKeyHex, message, signatureHex) {
30
+ isProcessing.value = true;
31
+ error.value = null;
32
+ try {
33
+ const valid = crypto_lib_1.crypto.verify(algo, publicKeyHex, message, signatureHex);
34
+ isValid.value = valid;
35
+ algorithm.value = algo;
36
+ return valid;
37
+ }
38
+ catch (err) {
39
+ error.value = err instanceof Error ? err : new Error(String(err));
40
+ throw error.value;
41
+ }
42
+ finally {
43
+ isProcessing.value = false;
44
+ }
45
+ }
46
+ function clear() {
47
+ signature.value = null;
48
+ isValid.value = null;
49
+ algorithm.value = null;
50
+ error.value = null;
51
+ }
52
+ return {
53
+ signature: (0, vue_1.readonly)(signature),
54
+ isValid: (0, vue_1.readonly)(isValid),
55
+ algorithm: (0, vue_1.readonly)(algorithm),
56
+ isProcessing: (0, vue_1.readonly)(isProcessing),
57
+ error: (0, vue_1.readonly)(error),
58
+ sign,
59
+ verify,
60
+ clear,
61
+ };
62
+ }
63
+ //# sourceMappingURL=useSignature.js.map
@@ -0,0 +1,11 @@
1
+ export { CryptoPlugin, CryptoSymbol } from "./plugin";
2
+ export type { CryptoPluginOptions } from "./plugin";
3
+ export { useKeypair } from "./composables/useKeypair";
4
+ export type { UseKeypairReturn } from "./composables/useKeypair";
5
+ export { useEncrypt } from "./composables/useEncrypt";
6
+ export type { UseEncryptReturn } from "./composables/useEncrypt";
7
+ export { useHash } from "./composables/useHash";
8
+ export type { UseHashReturn, HashAlgorithm } from "./composables/useHash";
9
+ export { useSignature } from "./composables/useSignature";
10
+ export type { UseSignatureReturn, SignAlgorithm, } from "./composables/useSignature";
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEtD,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAGpD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE1E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,YAAY,EACV,kBAAkB,EAClB,aAAa,GACd,MAAM,4BAA4B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useSignature = exports.useHash = exports.useEncrypt = exports.useKeypair = exports.CryptoSymbol = exports.CryptoPlugin = void 0;
4
+ var plugin_1 = require("./plugin");
5
+ Object.defineProperty(exports, "CryptoPlugin", { enumerable: true, get: function () { return plugin_1.CryptoPlugin; } });
6
+ Object.defineProperty(exports, "CryptoSymbol", { enumerable: true, get: function () { return plugin_1.CryptoSymbol; } });
7
+ var useKeypair_1 = require("./composables/useKeypair");
8
+ Object.defineProperty(exports, "useKeypair", { enumerable: true, get: function () { return useKeypair_1.useKeypair; } });
9
+ var useEncrypt_1 = require("./composables/useEncrypt");
10
+ Object.defineProperty(exports, "useEncrypt", { enumerable: true, get: function () { return useEncrypt_1.useEncrypt; } });
11
+ var useHash_1 = require("./composables/useHash");
12
+ Object.defineProperty(exports, "useHash", { enumerable: true, get: function () { return useHash_1.useHash; } });
13
+ var useSignature_1 = require("./composables/useSignature");
14
+ Object.defineProperty(exports, "useSignature", { enumerable: true, get: function () { return useSignature_1.useSignature; } });
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,11 @@
1
+ import type { App, InjectionKey } from "vue";
2
+ export interface CryptoPluginOptions {
3
+ defaultKey?: string;
4
+ serverUrl?: string;
5
+ apiKey?: string;
6
+ }
7
+ export declare const CryptoSymbol: InjectionKey<CryptoPluginOptions>;
8
+ export declare const CryptoPlugin: {
9
+ install(app: App, options?: CryptoPluginOptions): void;
10
+ };
11
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,KAAK,CAAC;AAa7C,MAAM,WAAW,mBAAmB;IAElC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAUD,eAAO,MAAM,YAAY,EAAE,YAAY,CAAC,mBAAmB,CAAoB,CAAC;AAYhF,eAAO,MAAM,YAAY;iBAEV,GAAG,YAAW,mBAAmB;CAG/C,CAAC"}
package/dist/plugin.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CryptoPlugin = exports.CryptoSymbol = void 0;
4
+ exports.CryptoSymbol = Symbol("crypto");
5
+ exports.CryptoPlugin = {
6
+ install(app, options = {}) {
7
+ app.provide(exports.CryptoSymbol, options);
8
+ },
9
+ };
10
+ //# sourceMappingURL=plugin.js.map
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@sebastienrousseau/crypto-vue",
3
+ "version": "0.0.7",
4
+ "description": "Vue 3 composables for client-side cryptography — key generation, encryption, signing, and hashing with reactive state.",
5
+ "author": "Sebastien Rousseau <sebastienrousseau@users.noreply.github.com>",
6
+ "license": "MIT OR Apache-2.0",
7
+ "homepage": "https://crypto-service.co",
8
+ "repository": {
9
+ "directory": "packages/crypto-vue",
10
+ "type": "git",
11
+ "url": "git@github.com:sebastienrousseau/crypto-service.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/sebastienrousseau/crypto-service/issues"
15
+ },
16
+ "engines": {
17
+ "node": ">=22.0.0"
18
+ },
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "sideEffects": false,
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "require": "./dist/index.js",
26
+ "import": "./dist/index.js"
27
+ }
28
+ },
29
+ "files": [
30
+ "dist/**/*.js",
31
+ "dist/**/*.d.ts",
32
+ "dist/**/*.d.ts.map"
33
+ ],
34
+ "dependencies": {
35
+ "@sebastienrousseau/crypto-lib": "0.0.7"
36
+ },
37
+ "peerDependencies": {
38
+ "vue": "^3.3.0"
39
+ },
40
+ "devDependencies": {
41
+ "@sebastienrousseau/mocha-config": "^0.0.5",
42
+ "@types/chai": "^4.3.7",
43
+ "@types/chai-as-promised": "^8.0.2",
44
+ "@types/mocha": "^10.0.2",
45
+ "@types/node": "^26.4.1",
46
+ "c8": "^12.0.0",
47
+ "chai": "^4.5.0",
48
+ "chai-as-promised": "^7.1.2",
49
+ "mocha": "^10.8.2",
50
+ "rimraf": "^6.1.3",
51
+ "ts-node": "^10.9.2",
52
+ "typedoc": "^0.28.20",
53
+ "typescript": "~5.9.3",
54
+ "vue": "^3.3.0"
55
+ },
56
+ "keywords": [
57
+ "vue",
58
+ "vue3",
59
+ "composables",
60
+ "cryptography",
61
+ "encryption",
62
+ "signing",
63
+ "hashing",
64
+ "post-quantum"
65
+ ],
66
+ "publishConfig": {
67
+ "access": "public"
68
+ },
69
+ "private": false,
70
+ "scripts": {
71
+ "build": "tsc --build tsconfig.json",
72
+ "clean": "rimraf ./coverage ./dist ./docs",
73
+ "test": "c8 --check-coverage --lines 100 --branches 100 --functions 100 --reporter=lcov --reporter=text mocha --config=.mocharc.cjs",
74
+ "docs": "typedoc",
75
+ "lint": "eslint --ext .ts src __tests__",
76
+ "lint:fix": "eslint --cache --fix --ext .ts src __tests__",
77
+ "format": "prettier --write src/**/*.ts",
78
+ "format:check": "prettier --check \"src/**/*.ts\""
79
+ }
80
+ }