@byearlybird/crypto 0.2.0 → 0.3.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.
package/dist/index.d.mts CHANGED
@@ -10,6 +10,15 @@ type AuthPayload = {
10
10
  timestamp: number;
11
11
  bodyHash?: string;
12
12
  };
13
+ type ValidateSuccess = {
14
+ ok: true;
15
+ data: AuthPayload;
16
+ };
17
+ type ValidateFailure = {
18
+ ok: false;
19
+ message: string;
20
+ };
21
+ type ValidateResult = ValidateSuccess | ValidateFailure;
13
22
  declare function deriveVaultId(publicKeyB64: string): Promise<string>;
14
23
  declare function createAuthHeader(args: {
15
24
  vaultId: string;
@@ -18,10 +27,14 @@ declare function createAuthHeader(args: {
18
27
  serializedBody?: string;
19
28
  privateKey: CryptoKey;
20
29
  }): Promise<string>;
21
- declare function parseAuthHeader(header: string): AuthPayload & {
22
- signature: string;
23
- };
24
- declare function verifyAuthHeader(header: string, publicKey: CryptoKey): Promise<boolean>;
30
+ declare function validateAuthHeader(header: string, options: {
31
+ publicKey: CryptoKey;
32
+ vaultId: string;
33
+ method: string;
34
+ path: string;
35
+ ttl: number;
36
+ body?: string;
37
+ }): Promise<ValidateResult>;
25
38
  //#endregion
26
39
  //#region src/encryption.d.ts
27
40
  declare function generateEncryptionKey(extractable?: boolean): Promise<crypto0.webcrypto.CryptoKey>;
@@ -44,4 +57,4 @@ declare function bytesToBase64(bytes: Uint8Array): string;
44
57
  declare function base64ToBytes(base64: string): Uint8Array;
45
58
  declare function hashString(value: string): Promise<string>;
46
59
  //#endregion
47
- export { AuthPayload, base64ToBytes, bytesToBase64, createAuthHeader, decrypt, deriveVaultId, encrypt, exportEncryptionKey, exportPrivateKey, exportPublicKey, generateEncryptionKey, generateSigningKeyPair, hashString, importEncryptionKey, importPrivateKey, importPublicKey, parseAuthHeader, sign, verify, verifyAuthHeader };
60
+ export { type AuthPayload, type ValidateFailure, type ValidateResult, type ValidateSuccess, base64ToBytes, bytesToBase64, createAuthHeader, decrypt, deriveVaultId, encrypt, exportEncryptionKey, exportPrivateKey, exportPublicKey, generateEncryptionKey, generateSigningKeyPair, hashString, importEncryptionKey, importPrivateKey, importPublicKey, sign, validateAuthHeader, verify };
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  //#region src/signing.ts
2
2
  async function generateSigningKeyPair(extractable = false) {
3
- return crypto.subtle.generateKey("Ed25519", extractable, ["sign", "verify"]);
3
+ return await crypto.subtle.generateKey("Ed25519", extractable, ["sign", "verify"]);
4
4
  }
5
5
  async function exportPublicKey(key) {
6
6
  const spki = await crypto.subtle.exportKey("spki", key);
@@ -54,6 +54,53 @@ async function createAuthHeader(args) {
54
54
  const payload = await generateAuthPayload(payloadArgs);
55
55
  return makeAuthHeader(payload, await sign(makeCanonicalString(payload), privateKey));
56
56
  }
57
+ async function validateAuthHeader(header, options) {
58
+ let parsed;
59
+ try {
60
+ parsed = parseAuthHeader(header);
61
+ } catch {
62
+ return {
63
+ ok: false,
64
+ message: "Malformed auth header"
65
+ };
66
+ }
67
+ const { signature,...payload } = parsed;
68
+ if (parsed.vaultId !== options.vaultId) return {
69
+ ok: false,
70
+ message: "Vault id mismatch"
71
+ };
72
+ if (parsed.method !== options.method) return {
73
+ ok: false,
74
+ message: "Method mismatch"
75
+ };
76
+ if (parsed.pathWithQuery !== options.path) return {
77
+ ok: false,
78
+ message: "Path mismatch"
79
+ };
80
+ if (Math.abs(Date.now() - parsed.timestamp) > options.ttl) return {
81
+ ok: false,
82
+ message: "Expired"
83
+ };
84
+ if (parsed.bodyHash) {
85
+ if (!options.body) return {
86
+ ok: false,
87
+ message: "Body hash mismatch"
88
+ };
89
+ const serverHash = await hashString(options.body);
90
+ if (parsed.bodyHash !== serverHash) return {
91
+ ok: false,
92
+ message: "Body hash mismatch"
93
+ };
94
+ }
95
+ if (!await verify(makeCanonicalString(payload), signature, options.publicKey)) return {
96
+ ok: false,
97
+ message: "Invalid signature"
98
+ };
99
+ return {
100
+ ok: true,
101
+ data: payload
102
+ };
103
+ }
57
104
  function parseAuthHeader(header) {
58
105
  const spaceIdx = header.indexOf(" ");
59
106
  if (spaceIdx === -1) throw new Error("Malformed auth header: missing scheme separator");
@@ -88,10 +135,6 @@ function parseAuthHeader(header) {
88
135
  if (bh) result.bodyHash = bh;
89
136
  return result;
90
137
  }
91
- async function verifyAuthHeader(header, publicKey) {
92
- const { signature,...payload } = parseAuthHeader(header);
93
- return verify(makeCanonicalString(payload), signature, publicKey);
94
- }
95
138
  async function generateAuthPayload(args) {
96
139
  const { serializedBody,...rest } = args;
97
140
  const nonce = crypto.randomUUID();
@@ -168,4 +211,4 @@ async function decrypt(encoded, key) {
168
211
  }
169
212
 
170
213
  //#endregion
171
- export { base64ToBytes, bytesToBase64, createAuthHeader, decrypt, deriveVaultId, encrypt, exportEncryptionKey, exportPrivateKey, exportPublicKey, generateEncryptionKey, generateSigningKeyPair, hashString, importEncryptionKey, importPrivateKey, importPublicKey, parseAuthHeader, sign, verify, verifyAuthHeader };
214
+ export { base64ToBytes, bytesToBase64, createAuthHeader, decrypt, deriveVaultId, encrypt, exportEncryptionKey, exportPrivateKey, exportPublicKey, generateEncryptionKey, generateSigningKeyPair, hashString, importEncryptionKey, importPrivateKey, importPublicKey, sign, validateAuthHeader, verify };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byearlybird/crypto",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Lightweight E2EE toolkit for web apps - zero dependencies + vault key security",
5
5
  "type": "module",
6
6
  "license": "MIT",