@welshare/react 0.3.0 → 0.5.0

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.
Files changed (53) hide show
  1. package/README.md +37 -48
  2. package/dist/esm/components/connect-button.d.ts.map +1 -1
  3. package/dist/esm/components/connect-button.js +1 -4
  4. package/dist/esm/components/welshare-logo.d.ts +1 -1
  5. package/dist/esm/hooks/use-welshare.d.ts.map +1 -1
  6. package/dist/esm/hooks/use-welshare.js +11 -8
  7. package/dist/esm/index.d.ts +1 -2
  8. package/dist/esm/index.d.ts.map +1 -1
  9. package/dist/esm/index.js +3 -3
  10. package/dist/esm/lib/uploads.d.ts +1 -1
  11. package/dist/esm/lib/uploads.d.ts.map +1 -1
  12. package/dist/esm/lib/uploads.js +2 -4
  13. package/dist/esm/types.d.ts +1 -1
  14. package/dist/esm/types.d.ts.map +1 -1
  15. package/dist/node_modules/@welshare/react/.turbo/turbo-lint.log +14 -0
  16. package/dist/node_modules/@welshare/react/README.md +37 -48
  17. package/dist/node_modules/@welshare/react/dist/esm/components/connect-button.d.ts.map +1 -1
  18. package/dist/node_modules/@welshare/react/dist/esm/components/connect-button.js +1 -4
  19. package/dist/node_modules/@welshare/react/dist/esm/components/welshare-logo.d.ts +1 -1
  20. package/dist/node_modules/@welshare/react/dist/esm/hooks/use-welshare.d.ts.map +1 -1
  21. package/dist/node_modules/@welshare/react/dist/esm/hooks/use-welshare.js +11 -8
  22. package/dist/node_modules/@welshare/react/dist/esm/index.d.ts +1 -2
  23. package/dist/node_modules/@welshare/react/dist/esm/index.d.ts.map +1 -1
  24. package/dist/node_modules/@welshare/react/dist/esm/index.js +3 -3
  25. package/dist/node_modules/@welshare/react/dist/esm/lib/uploads.d.ts +1 -1
  26. package/dist/node_modules/@welshare/react/dist/esm/lib/uploads.d.ts.map +1 -1
  27. package/dist/node_modules/@welshare/react/dist/esm/lib/uploads.js +2 -4
  28. package/dist/node_modules/@welshare/react/dist/esm/types.d.ts +1 -1
  29. package/dist/node_modules/@welshare/react/dist/esm/types.d.ts.map +1 -1
  30. package/dist/node_modules/@welshare/react/eslint.config.mjs +2 -2
  31. package/dist/node_modules/@welshare/react/package.json +1 -8
  32. package/dist/node_modules/@welshare/react/src/components/connect-button.tsx +1 -4
  33. package/dist/node_modules/@welshare/react/src/components/welshare-logo.tsx +1 -1
  34. package/dist/node_modules/@welshare/react/src/hooks/use-welshare.ts +18 -10
  35. package/dist/node_modules/@welshare/react/src/index.ts +8 -4
  36. package/dist/node_modules/@welshare/react/src/lib/uploads.ts +4 -6
  37. package/dist/node_modules/@welshare/react/src/types.ts +12 -11
  38. package/dist/node_modules/@welshare/react/tsconfig.json +3 -12
  39. package/package.json +2 -9
  40. package/dist/esm/lib/encryption.d.ts +0 -9
  41. package/dist/esm/lib/encryption.d.ts.map +0 -1
  42. package/dist/esm/lib/encryption.js +0 -54
  43. package/dist/esm/utils.d.ts +0 -12
  44. package/dist/esm/utils.d.ts.map +0 -1
  45. package/dist/esm/utils.js +0 -8
  46. package/dist/node_modules/@welshare/react/dist/esm/lib/encryption.d.ts +0 -9
  47. package/dist/node_modules/@welshare/react/dist/esm/lib/encryption.d.ts.map +0 -1
  48. package/dist/node_modules/@welshare/react/dist/esm/lib/encryption.js +0 -54
  49. package/dist/node_modules/@welshare/react/dist/esm/utils.d.ts +0 -12
  50. package/dist/node_modules/@welshare/react/dist/esm/utils.d.ts.map +0 -1
  51. package/dist/node_modules/@welshare/react/dist/esm/utils.js +0 -8
  52. package/dist/node_modules/@welshare/react/src/lib/encryption.ts +0 -89
  53. package/dist/node_modules/@welshare/react/src/utils.ts +0 -22
@@ -1,4 +1,4 @@
1
- import { config } from "@workspace/eslint-config/react-internal"
1
+ import { config } from "@workspace/eslint-config/react-internal";
2
2
 
3
3
  /** @type {import("eslint").Linter.Config} */
4
- export default config
4
+ export default config;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@welshare/react",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "React library for integrating with Welshare's sovereign data sharing platform",
5
5
  "keywords": [
6
6
  "react",
@@ -61,7 +61,6 @@
61
61
  "exports": {
62
62
  "./package.json": "./package.json",
63
63
  "./types": "./src/types.ts",
64
- "./utils": "./src/utils.ts",
65
64
  ".": "./src/index.ts"
66
65
  }
67
66
  },
@@ -73,12 +72,6 @@
73
72
  "default": "./dist/esm/types.js"
74
73
  }
75
74
  },
76
- "./utils": {
77
- "import": {
78
- "types": "./dist/esm/utils.d.ts",
79
- "default": "./dist/esm/utils.js"
80
- }
81
- },
82
75
  ".": {
83
76
  "import": {
84
77
  "types": "./dist/esm/index.d.ts",
@@ -89,10 +89,7 @@ export const ConnectWelshareButton = (props: {
89
89
  <WelshareLogo
90
90
  width={24}
91
91
  height={18}
92
- style={{
93
- "marginRight": "4px",
94
- color: "#ffffff",
95
- }}
92
+ style={{ marginRight: "4px", color: "#ffffff" }}
96
93
  />
97
94
  </span>
98
95
  <span>Connect Welshare Profile</span>
@@ -1,4 +1,4 @@
1
- import React from 'react';
1
+ import React from "react";
2
2
 
3
3
  export interface WelshareLogoProps {
4
4
  className?: string;
@@ -8,7 +8,10 @@ import {
8
8
  UploadCredentials,
9
9
  WelshareConnectionOptions,
10
10
  } from "@/types.js";
11
- import { getBaseUrl, WELSHARE_API_ENVIRONMENT } from "@welshare/sdk/environment";
11
+ import {
12
+ getBaseUrl,
13
+ WELSHARE_API_ENVIRONMENT,
14
+ } from "@welshare/sdk/environment";
12
15
  import { useEffect, useRef, useState } from "react";
13
16
  import { encryptAndUploadFile } from "../lib/uploads.js";
14
17
 
@@ -28,7 +31,7 @@ export const useWelshare = (props: WelshareConnectionOptions) => {
28
31
  // Resolve the base URL from environment or apiBaseUrl
29
32
  const resolvedBaseUrl = props.environment
30
33
  ? getBaseUrl(props.environment)
31
- : props.apiBaseUrl ?? getBaseUrl(WELSHARE_API_ENVIRONMENT.production);
34
+ : (props.apiBaseUrl ?? getBaseUrl(WELSHARE_API_ENVIRONMENT.production));
32
35
 
33
36
  const options: WelshareConnectionOptions = {
34
37
  ...props,
@@ -187,7 +190,13 @@ export const useWelshare = (props: WelshareConnectionOptions) => {
187
190
  return () => {
188
191
  window.removeEventListener("message", handleMessage);
189
192
  };
190
- }, [WELSHARE_WALLET_URL, dialogWindow, messageIdCounter, options.applicationId, options.callbacks]);
193
+ }, [
194
+ WELSHARE_WALLET_URL,
195
+ dialogWindow,
196
+ messageIdCounter,
197
+ options.applicationId,
198
+ options.callbacks,
199
+ ]);
191
200
 
192
201
  /**
193
202
  * Starts a file upload and returns a promise that resolves with the uploaded file URL
@@ -225,10 +234,7 @@ export const useWelshare = (props: WelshareConnectionOptions) => {
225
234
  const message: DialogMessage = {
226
235
  type: "REQUEST_UPLOAD_CREDENTIALS",
227
236
  id: String(messageIdCounter),
228
- payload: {
229
- ...payload,
230
- applicationId: options.applicationId,
231
- },
237
+ payload: { ...payload, applicationId: options.applicationId },
232
238
  };
233
239
 
234
240
  dialogWindow.postMessage(message, WELSHARE_WALLET_URL);
@@ -282,10 +288,12 @@ export const useWelshare = (props: WelshareConnectionOptions) => {
282
288
  if (options.interpolateSocials) {
283
289
  const socialEntries = Object.entries(options.interpolateSocials)
284
290
  .filter(([_, value]) => value !== undefined && value !== null)
285
- .map(([key, value]) => `social.${key}=${encodeURIComponent(String(value))}`);
286
-
291
+ .map(
292
+ ([key, value]) => `social.${key}=${encodeURIComponent(String(value))}`
293
+ );
294
+
287
295
  if (socialEntries.length > 0) {
288
- socialParams = `&${socialEntries.join('&')}`;
296
+ socialParams = `&${socialEntries.join("&")}`;
289
297
  }
290
298
  }
291
299
 
@@ -15,15 +15,19 @@ export {
15
15
  type NillionClusterConfig,
16
16
  } from "@welshare/sdk/environment";
17
17
 
18
- // ---- Utils ----
18
+ // ---- Encryption utilities (re-exported from @welshare/sdk) ----
19
19
  export {
20
20
  decrypt,
21
21
  encodeEncryptionKey,
22
22
  encryptFile,
23
- generateRandomAESKey
24
- } from "./lib/encryption.js";
25
- export { decodeEncryptionKey, type EncryptionKey } from "./utils.js";
23
+ generateRandomAESKey,
24
+ decodeEncryptionKey,
25
+ ALGORITHM,
26
+ type EncryptionKey,
27
+ type Algorithm,
28
+ } from "@welshare/sdk";
26
29
 
30
+ // ---- Upload utilities (local, for frame-based upload flow) ----
27
31
  export { browserDownload, encryptAndUploadFile } from "./lib/uploads.js";
28
32
 
29
33
  //todo: import them from the SDK
@@ -1,9 +1,9 @@
1
- import { EncryptionKey } from "@/utils.js";
2
1
  import {
2
+ type EncryptionKey,
3
3
  encodeEncryptionKey,
4
4
  encryptFile,
5
5
  generateRandomAESKey,
6
- } from "./encryption.js";
6
+ } from "@welshare/sdk";
7
7
 
8
8
  export const encryptAndUploadFile = async (
9
9
  file: File,
@@ -16,9 +16,7 @@ export const encryptAndUploadFile = async (
16
16
  const uploadResponse = await fetch(presignedUrl, {
17
17
  method: "PUT",
18
18
  body: encryptedData,
19
- headers: {
20
- "Content-Type": file.type,
21
- },
19
+ headers: { "Content-Type": file.type },
22
20
  });
23
21
 
24
22
  if (!uploadResponse.ok) {
@@ -37,4 +35,4 @@ export const browserDownload = (decryptedFile: File) => {
37
35
  a.click();
38
36
  document.body.removeChild(a);
39
37
  window.URL.revokeObjectURL(downloadUrl);
40
- }
38
+ };
@@ -1,5 +1,8 @@
1
- import { EncryptionKey } from "./utils.js";
2
- import type { WelshareApiEnvironment, WelshareEnvironmentName } from "@welshare/sdk/environment";
1
+ import type { EncryptionKey } from "@welshare/sdk";
2
+ import type {
3
+ WelshareApiEnvironment,
4
+ WelshareEnvironmentName,
5
+ } from "@welshare/sdk/environment";
3
6
 
4
7
  export interface DialogMessage {
5
8
  type: string;
@@ -10,7 +13,7 @@ export interface DialogMessage {
10
13
  /**
11
14
  * a welshare schema type uid
12
15
  */
13
- export type SubmissionSchemaId = string
16
+ export type SubmissionSchemaId = string;
14
17
 
15
18
  export interface SubmissionPayload<T> {
16
19
  applicationId: string;
@@ -19,10 +22,7 @@ export interface SubmissionPayload<T> {
19
22
  submission: T;
20
23
  }
21
24
 
22
- export type UploadCredentials = {
23
- presignedUrl: string;
24
- uploadKey: string;
25
- }
25
+ export type UploadCredentials = { presignedUrl: string; uploadKey: string };
26
26
 
27
27
  export interface RequestUploadCredentialsPayload {
28
28
  timestamp?: Date;
@@ -32,7 +32,8 @@ export interface RequestUploadCredentialsPayload {
32
32
  fileType: string;
33
33
  }
34
34
 
35
- export interface BinaryFileSubmissionPayload extends RequestUploadCredentialsPayload {
35
+ export interface BinaryFileSubmissionPayload
36
+ extends RequestUploadCredentialsPayload {
36
37
  encryptionKey: EncryptionKey;
37
38
  /// in bytes
38
39
  fileSize: number;
@@ -50,8 +51,8 @@ export interface RunningFileUpload extends RequestUploadCredentialsPayload {
50
51
  }
51
52
 
52
53
  export interface DataSubmissionDialogMessage extends DialogMessage {
53
- payload:
54
- | SubmissionPayload<unknown>
54
+ payload:
55
+ | SubmissionPayload<unknown>
55
56
  | BinaryFileSubmissionPayload
56
57
  | RequestUploadCredentialsPayload;
57
58
  }
@@ -62,7 +63,7 @@ export interface WelshareConnectionOptions {
62
63
  emailAddress?: string;
63
64
  privy?: string;
64
65
  twitter?: string;
65
- }
66
+ };
66
67
  /**
67
68
  * The Welshare environment to connect to.
68
69
  * Can be an environment name ('production', 'staging', etc.) or a full environment object.
@@ -2,20 +2,11 @@
2
2
  "extends": "@workspace/typescript-config/react-library.json",
3
3
  "compilerOptions": {
4
4
  "baseUrl": ".",
5
- "paths": {
6
- "@/*": ["./src/*"],
7
- "@/types/*": ["./types/*"],
8
- },
9
- "plugins": [
10
- ],
5
+ "paths": { "@/*": ["./src/*"], "@/types/*": ["./types/*"] },
6
+ "plugins": [],
11
7
  "allowJs": true,
12
8
  "jsx": "react-jsx"
13
9
  },
14
- "include": [
15
- "next-env.d.ts",
16
- "next.config.ts",
17
- "**/*.ts",
18
- "**/*.tsx",
19
- ],
10
+ "include": ["next-env.d.ts", "next.config.ts", "**/*.ts", "**/*.tsx"],
20
11
  "exclude": ["node_modules"]
21
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@welshare/react",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "React library for integrating with Welshare's sovereign data sharing platform",
5
5
  "keywords": [
6
6
  "react",
@@ -23,7 +23,7 @@
23
23
  "homepage": "https://welshare.health",
24
24
  "type": "module",
25
25
  "dependencies": {
26
- "@welshare/sdk": "0.1.4"
26
+ "@welshare/sdk": "0.3.0"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "react": "^19",
@@ -52,7 +52,6 @@
52
52
  "exports": {
53
53
  "./package.json": "./package.json",
54
54
  "./types": "./src/types.ts",
55
- "./utils": "./src/utils.ts",
56
55
  ".": "./src/index.ts"
57
56
  }
58
57
  },
@@ -64,12 +63,6 @@
64
63
  "default": "./dist/esm/types.js"
65
64
  }
66
65
  },
67
- "./utils": {
68
- "import": {
69
- "types": "./dist/esm/utils.d.ts",
70
- "default": "./dist/esm/utils.js"
71
- }
72
- },
73
66
  ".": {
74
67
  "import": {
75
68
  "types": "./dist/esm/index.d.ts",
@@ -1,9 +0,0 @@
1
- import { EncryptionKey } from "../utils.js";
2
- export declare const generateRandomAESKey: () => Promise<CryptoKey>;
3
- export declare const encryptFile: (file: File, key: CryptoKey) => Promise<{
4
- encryptedData: ArrayBuffer;
5
- iv: Uint8Array;
6
- }>;
7
- export declare const encodeEncryptionKey: (key: CryptoKey, iv: Uint8Array) => Promise<EncryptionKey>;
8
- export declare const decrypt: (encryptedData: ArrayBuffer, encryptionKey: EncryptionKey) => Promise<ArrayBuffer | null>;
9
- //# sourceMappingURL=encryption.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../../src/lib/encryption.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,aAAa,EAAuB,MAAM,aAAa,CAAC;AAE5E,eAAO,MAAM,oBAAoB,QAAa,OAAO,CAAC,SAAS,CAU9D,CAAC;AAIF,eAAO,MAAM,WAAW,SAChB,IAAI,OACL,SAAS,KACb,OAAO,CAAC;IAAE,aAAa,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,UAAU,CAAA;CAAE,CAgBxD,CAAC;AAEF,eAAO,MAAM,mBAAmB,QACzB,SAAS,MACV,UAAU,KACb,OAAO,CAAC,aAAa,CAgBvB,CAAC;AAGF,eAAO,MAAM,OAAO,kBACH,WAAW,iBACX,aAAa,KAC3B,OAAO,CAAC,WAAW,GAAG,IAAI,CA0B5B,CAAC"}
@@ -1,54 +0,0 @@
1
- import { ALGORITHM, decodeEncryptionKey } from "../utils.js";
2
- export const generateRandomAESKey = async () => {
3
- // Generate a 256-bit AES-GCM key for file encryption
4
- return window.crypto.subtle.generateKey({
5
- name: ALGORITHM,
6
- length: 256, // 256-bit key
7
- }, true, // Key is extractable (needed for storage/transmission)
8
- ["encrypt", "decrypt"] // Key usage
9
- );
10
- };
11
- /// also Generates random IV (12 bytes for AES-GCM)
12
- /// @return {arraybuffer ciphertext, uint8array iv}
13
- export const encryptFile = async (file, key) => {
14
- // Read file as ArrayBuffer
15
- const fileData = await file.arrayBuffer();
16
- const iv = window.crypto.getRandomValues(new Uint8Array(12));
17
- // Encrypt the file data
18
- const encryptedData = await window.crypto.subtle.encrypt({
19
- name: ALGORITHM,
20
- iv: iv,
21
- }, key, fileData);
22
- return { encryptedData, iv };
23
- };
24
- export const encodeEncryptionKey = async (key, iv) => {
25
- // Export the key as raw bytes
26
- const exportedKey = await window.crypto.subtle.exportKey("raw", key);
27
- const keyHex = Array.from(new Uint8Array(exportedKey))
28
- .map((b) => b.toString(16).padStart(2, "0"))
29
- .join("");
30
- const ivHex = Array.from(iv)
31
- .map((b) => b.toString(16).padStart(2, "0"))
32
- .join("");
33
- return {
34
- algorithm: ALGORITHM,
35
- key: keyHex,
36
- iv: ivHex,
37
- };
38
- };
39
- // Helper function to decrypt a file using encoded encryption key
40
- export const decrypt = async (encryptedData, encryptionKey) => {
41
- try {
42
- const { key: keyBytes, iv } = decodeEncryptionKey(encryptionKey);
43
- const key = await window.crypto.subtle.importKey("raw", keyBytes, { name: ALGORITHM }, false, ["decrypt"]);
44
- const decryptedData = await window.crypto.subtle.decrypt({
45
- name: ALGORITHM,
46
- iv: iv,
47
- }, key, encryptedData);
48
- return decryptedData;
49
- }
50
- catch (error) {
51
- console.error("Failed to decrypt file:", error);
52
- return null;
53
- }
54
- };
@@ -1,12 +0,0 @@
1
- export declare const ALGORITHM = "AES-GCM";
2
- export type Algorithm = "AES-GCM";
3
- export type EncryptionKey = {
4
- algorithm: Algorithm;
5
- key: string;
6
- iv: string;
7
- };
8
- export declare const decodeEncryptionKey: (encryptionKey: EncryptionKey) => {
9
- key: BufferSource;
10
- iv: BufferSource;
11
- };
12
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,YAAY,CAAC;AACnC,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC;AAElC,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,SAAS,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,eAAO,MAAM,mBAAmB,kBACf,aAAa,KAC3B;IAAE,GAAG,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,YAAY,CAAA;CAUvC,CAAC"}
package/dist/esm/utils.js DELETED
@@ -1,8 +0,0 @@
1
- export const ALGORITHM = "AES-GCM";
2
- export const decodeEncryptionKey = (encryptionKey) => {
3
- const keyBytes = new Uint8Array(encryptionKey.key
4
- .match(/.{1,2}/g)
5
- .map((byte) => parseInt(byte, 16)));
6
- const ivBytes = new Uint8Array(encryptionKey.iv.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
7
- return { key: keyBytes, iv: ivBytes };
8
- };
@@ -1,9 +0,0 @@
1
- import { EncryptionKey } from "../utils.js";
2
- export declare const generateRandomAESKey: () => Promise<CryptoKey>;
3
- export declare const encryptFile: (file: File, key: CryptoKey) => Promise<{
4
- encryptedData: ArrayBuffer;
5
- iv: Uint8Array;
6
- }>;
7
- export declare const encodeEncryptionKey: (key: CryptoKey, iv: Uint8Array) => Promise<EncryptionKey>;
8
- export declare const decrypt: (encryptedData: ArrayBuffer, encryptionKey: EncryptionKey) => Promise<ArrayBuffer | null>;
9
- //# sourceMappingURL=encryption.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../../src/lib/encryption.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,aAAa,EAAuB,MAAM,aAAa,CAAC;AAE5E,eAAO,MAAM,oBAAoB,QAAa,OAAO,CAAC,SAAS,CAU9D,CAAC;AAIF,eAAO,MAAM,WAAW,SAChB,IAAI,OACL,SAAS,KACb,OAAO,CAAC;IAAE,aAAa,EAAE,WAAW,CAAC;IAAC,EAAE,EAAE,UAAU,CAAA;CAAE,CAgBxD,CAAC;AAEF,eAAO,MAAM,mBAAmB,QACzB,SAAS,MACV,UAAU,KACb,OAAO,CAAC,aAAa,CAgBvB,CAAC;AAGF,eAAO,MAAM,OAAO,kBACH,WAAW,iBACX,aAAa,KAC3B,OAAO,CAAC,WAAW,GAAG,IAAI,CA0B5B,CAAC"}
@@ -1,54 +0,0 @@
1
- import { ALGORITHM, decodeEncryptionKey } from "../utils.js";
2
- export const generateRandomAESKey = async () => {
3
- // Generate a 256-bit AES-GCM key for file encryption
4
- return window.crypto.subtle.generateKey({
5
- name: ALGORITHM,
6
- length: 256, // 256-bit key
7
- }, true, // Key is extractable (needed for storage/transmission)
8
- ["encrypt", "decrypt"] // Key usage
9
- );
10
- };
11
- /// also Generates random IV (12 bytes for AES-GCM)
12
- /// @return {arraybuffer ciphertext, uint8array iv}
13
- export const encryptFile = async (file, key) => {
14
- // Read file as ArrayBuffer
15
- const fileData = await file.arrayBuffer();
16
- const iv = window.crypto.getRandomValues(new Uint8Array(12));
17
- // Encrypt the file data
18
- const encryptedData = await window.crypto.subtle.encrypt({
19
- name: ALGORITHM,
20
- iv: iv,
21
- }, key, fileData);
22
- return { encryptedData, iv };
23
- };
24
- export const encodeEncryptionKey = async (key, iv) => {
25
- // Export the key as raw bytes
26
- const exportedKey = await window.crypto.subtle.exportKey("raw", key);
27
- const keyHex = Array.from(new Uint8Array(exportedKey))
28
- .map((b) => b.toString(16).padStart(2, "0"))
29
- .join("");
30
- const ivHex = Array.from(iv)
31
- .map((b) => b.toString(16).padStart(2, "0"))
32
- .join("");
33
- return {
34
- algorithm: ALGORITHM,
35
- key: keyHex,
36
- iv: ivHex,
37
- };
38
- };
39
- // Helper function to decrypt a file using encoded encryption key
40
- export const decrypt = async (encryptedData, encryptionKey) => {
41
- try {
42
- const { key: keyBytes, iv } = decodeEncryptionKey(encryptionKey);
43
- const key = await window.crypto.subtle.importKey("raw", keyBytes, { name: ALGORITHM }, false, ["decrypt"]);
44
- const decryptedData = await window.crypto.subtle.decrypt({
45
- name: ALGORITHM,
46
- iv: iv,
47
- }, key, encryptedData);
48
- return decryptedData;
49
- }
50
- catch (error) {
51
- console.error("Failed to decrypt file:", error);
52
- return null;
53
- }
54
- };
@@ -1,12 +0,0 @@
1
- export declare const ALGORITHM = "AES-GCM";
2
- export type Algorithm = "AES-GCM";
3
- export type EncryptionKey = {
4
- algorithm: Algorithm;
5
- key: string;
6
- iv: string;
7
- };
8
- export declare const decodeEncryptionKey: (encryptionKey: EncryptionKey) => {
9
- key: BufferSource;
10
- iv: BufferSource;
11
- };
12
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,YAAY,CAAC;AACnC,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC;AAElC,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,SAAS,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC;AAEF,eAAO,MAAM,mBAAmB,kBACf,aAAa,KAC3B;IAAE,GAAG,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,YAAY,CAAA;CAUvC,CAAC"}
@@ -1,8 +0,0 @@
1
- export const ALGORITHM = "AES-GCM";
2
- export const decodeEncryptionKey = (encryptionKey) => {
3
- const keyBytes = new Uint8Array(encryptionKey.key
4
- .match(/.{1,2}/g)
5
- .map((byte) => parseInt(byte, 16)));
6
- const ivBytes = new Uint8Array(encryptionKey.iv.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
7
- return { key: keyBytes, iv: ivBytes };
8
- };
@@ -1,89 +0,0 @@
1
- import { ALGORITHM, EncryptionKey, decodeEncryptionKey } from "../utils.js";
2
-
3
- export const generateRandomAESKey = async (): Promise<CryptoKey> => {
4
- // Generate a 256-bit AES-GCM key for file encryption
5
- return window.crypto.subtle.generateKey(
6
- {
7
- name: ALGORITHM,
8
- length: 256, // 256-bit key
9
- },
10
- true, // Key is extractable (needed for storage/transmission)
11
- ["encrypt", "decrypt"] // Key usage
12
- );
13
- };
14
-
15
- /// also Generates random IV (12 bytes for AES-GCM)
16
- /// @return {arraybuffer ciphertext, uint8array iv}
17
- export const encryptFile = async (
18
- file: File,
19
- key: CryptoKey
20
- ): Promise<{ encryptedData: ArrayBuffer; iv: Uint8Array }> => {
21
- // Read file as ArrayBuffer
22
- const fileData = await file.arrayBuffer();
23
- const iv = window.crypto.getRandomValues(new Uint8Array(12));
24
-
25
- // Encrypt the file data
26
- const encryptedData = await window.crypto.subtle.encrypt(
27
- {
28
- name: ALGORITHM,
29
- iv: iv,
30
- },
31
- key,
32
- fileData
33
- );
34
-
35
- return { encryptedData, iv };
36
- };
37
-
38
- export const encodeEncryptionKey = async (
39
- key: CryptoKey,
40
- iv: Uint8Array
41
- ): Promise<EncryptionKey> => {
42
- // Export the key as raw bytes
43
- const exportedKey = await window.crypto.subtle.exportKey("raw", key);
44
- const keyHex = Array.from(new Uint8Array(exportedKey))
45
- .map((b) => b.toString(16).padStart(2, "0"))
46
- .join("");
47
-
48
- const ivHex = Array.from(iv)
49
- .map((b) => b.toString(16).padStart(2, "0"))
50
- .join("");
51
-
52
- return {
53
- algorithm: ALGORITHM,
54
- key: keyHex,
55
- iv: ivHex,
56
- };
57
- };
58
-
59
- // Helper function to decrypt a file using encoded encryption key
60
- export const decrypt = async (
61
- encryptedData: ArrayBuffer,
62
- encryptionKey: EncryptionKey
63
- ): Promise<ArrayBuffer | null> => {
64
- try {
65
- const { key: keyBytes, iv } = decodeEncryptionKey(encryptionKey);
66
-
67
- const key = await window.crypto.subtle.importKey(
68
- "raw",
69
- keyBytes as BufferSource,
70
- { name: ALGORITHM },
71
- false,
72
- ["decrypt"]
73
- );
74
-
75
- const decryptedData = await window.crypto.subtle.decrypt(
76
- {
77
- name: ALGORITHM,
78
- iv: iv as BufferSource,
79
- },
80
- key,
81
- encryptedData
82
- );
83
-
84
- return decryptedData;
85
- } catch (error) {
86
- console.error("Failed to decrypt file:", error);
87
- return null;
88
- }
89
- };
@@ -1,22 +0,0 @@
1
- export const ALGORITHM = "AES-GCM";
2
- export type Algorithm = "AES-GCM";
3
-
4
- export type EncryptionKey = {
5
- algorithm: Algorithm;
6
- key: string;
7
- iv: string;
8
- };
9
-
10
- export const decodeEncryptionKey = (
11
- encryptionKey: EncryptionKey
12
- ): { key: BufferSource; iv: BufferSource } => {
13
- const keyBytes = new Uint8Array(
14
- encryptionKey.key
15
- .match(/.{1,2}/g)!
16
- .map((byte: string) => parseInt(byte, 16))
17
- );
18
- const ivBytes = new Uint8Array(
19
- encryptionKey.iv.match(/.{1,2}/g)!.map((byte: string) => parseInt(byte, 16))
20
- );
21
- return { key: keyBytes, iv: ivBytes };
22
- };