@scayle/h3-session 0.5.1 → 0.6.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/CHANGELOG.md +6 -0
- package/dist/index.mjs +40 -19
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -3,6 +3,41 @@ import { getCookie, setCookie } from 'h3';
|
|
|
3
3
|
import { defu } from 'defu';
|
|
4
4
|
import { subtle, randomUUID } from 'uncrypto';
|
|
5
5
|
|
|
6
|
+
const _signKeys = {};
|
|
7
|
+
async function getCryptoSignKey(secret) {
|
|
8
|
+
if (_signKeys[secret]) {
|
|
9
|
+
return _signKeys[secret];
|
|
10
|
+
}
|
|
11
|
+
const encoder = new TextEncoder();
|
|
12
|
+
const keyUint8Array = encoder.encode(secret);
|
|
13
|
+
const cryptoKey = await subtle.importKey(
|
|
14
|
+
"raw",
|
|
15
|
+
keyUint8Array,
|
|
16
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
17
|
+
false,
|
|
18
|
+
["sign"]
|
|
19
|
+
);
|
|
20
|
+
_signKeys[secret] = cryptoKey;
|
|
21
|
+
return cryptoKey;
|
|
22
|
+
}
|
|
23
|
+
const _verifyKeys = {};
|
|
24
|
+
async function getCryptoVerifyKey(secret) {
|
|
25
|
+
if (_verifyKeys[secret]) {
|
|
26
|
+
return _verifyKeys[secret];
|
|
27
|
+
}
|
|
28
|
+
const encoder = new TextEncoder();
|
|
29
|
+
const keyUint8Array = encoder.encode(secret);
|
|
30
|
+
const cryptoKey = await subtle.importKey(
|
|
31
|
+
"raw",
|
|
32
|
+
keyUint8Array,
|
|
33
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
34
|
+
false,
|
|
35
|
+
["verify"]
|
|
36
|
+
);
|
|
37
|
+
_verifyKeys[secret] = cryptoKey;
|
|
38
|
+
return cryptoKey;
|
|
39
|
+
}
|
|
40
|
+
|
|
6
41
|
class Session {
|
|
7
42
|
#id;
|
|
8
43
|
#store;
|
|
@@ -60,7 +95,7 @@ class UnstorageSessionStore {
|
|
|
60
95
|
*/
|
|
61
96
|
async get(sid) {
|
|
62
97
|
const item = await this.storage.getItem(this.getKey(sid));
|
|
63
|
-
return item ??
|
|
98
|
+
return item ?? undefined;
|
|
64
99
|
}
|
|
65
100
|
/**
|
|
66
101
|
* Save the session with the specified session ID
|
|
@@ -131,11 +166,11 @@ class UnstorageSessionStore {
|
|
|
131
166
|
const signatureLength = 43;
|
|
132
167
|
function parseCookieValue(value) {
|
|
133
168
|
if (value.length < signatureLength + 3) {
|
|
134
|
-
return
|
|
169
|
+
return undefined;
|
|
135
170
|
}
|
|
136
171
|
const separatorIndex = value.length - signatureLength - 1;
|
|
137
172
|
if (value.charAt(0) !== "s" || value.charAt(1) !== ":" || value.charAt(separatorIndex) !== ".") {
|
|
138
|
-
return
|
|
173
|
+
return undefined;
|
|
139
174
|
}
|
|
140
175
|
return [
|
|
141
176
|
value.substring(2, separatorIndex),
|
|
@@ -152,14 +187,7 @@ async function unsignCookie(value, secrets) {
|
|
|
152
187
|
const messageUint8Array = encoder.encode(message);
|
|
153
188
|
const signatureUint8Array = Uint8Array.from(Buffer.from(signature, "base64"));
|
|
154
189
|
for (let i = 0; i < secrets.length; i++) {
|
|
155
|
-
const
|
|
156
|
-
const cryptoKey = await subtle.importKey(
|
|
157
|
-
"raw",
|
|
158
|
-
keyUint8Array,
|
|
159
|
-
{ name: "HMAC", hash: "SHA-256" },
|
|
160
|
-
false,
|
|
161
|
-
["verify"]
|
|
162
|
-
);
|
|
190
|
+
const cryptoKey = await getCryptoVerifyKey(secrets[i]);
|
|
163
191
|
const result = await subtle.verify(
|
|
164
192
|
"HMAC",
|
|
165
193
|
cryptoKey,
|
|
@@ -181,14 +209,7 @@ async function signCookie(value, secret) {
|
|
|
181
209
|
}
|
|
182
210
|
const encoder = new TextEncoder();
|
|
183
211
|
const messageUint8Array = encoder.encode(value);
|
|
184
|
-
const
|
|
185
|
-
const cryptoKey = await subtle.importKey(
|
|
186
|
-
"raw",
|
|
187
|
-
keyUint8Array,
|
|
188
|
-
{ name: "HMAC", hash: "SHA-256" },
|
|
189
|
-
false,
|
|
190
|
-
["sign"]
|
|
191
|
-
);
|
|
212
|
+
const cryptoKey = await getCryptoSignKey(secret);
|
|
192
213
|
const signature = await subtle.sign("HMAC", cryptoKey, messageUint8Array);
|
|
193
214
|
const b64Signature = Buffer.from(signature).toString("base64").replace(/=+$/, "");
|
|
194
215
|
return `s:${value}.${b64Signature}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scayle/h3-session",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Persistent sessions for h3",
|
|
5
5
|
"author": "SCAYLE Commerce Engine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"lint": "eslint . --format gitlab",
|
|
25
25
|
"lint:fix": "eslint . --fix",
|
|
26
26
|
"test": "vitest run",
|
|
27
|
-
"test:ci": "vitest --run --coverage --reporter=default --reporter=junit --outputFile=./junit.xml",
|
|
27
|
+
"test:ci": "vitest --run --coverage --reporter=default --reporter=junit --outputFile=./coverage/junit.xml",
|
|
28
28
|
"test:watch": "vitest watch",
|
|
29
29
|
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
30
30
|
},
|
|
@@ -37,18 +37,18 @@
|
|
|
37
37
|
"unstorage": "^1.10.2"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@arethetypeswrong/cli": "0.17.
|
|
41
|
-
"@scayle/eslint-config-storefront": "4.4.
|
|
40
|
+
"@arethetypeswrong/cli": "0.17.3",
|
|
41
|
+
"@scayle/eslint-config-storefront": "4.4.1",
|
|
42
42
|
"cookie-es": "1.2.2",
|
|
43
43
|
"dprint": "0.48.0",
|
|
44
|
-
"eslint": "9.
|
|
44
|
+
"eslint": "9.18.0",
|
|
45
45
|
"eslint-formatter-gitlab": "5.1.0",
|
|
46
|
-
"h3": "1.13.
|
|
47
|
-
"typescript": "5.7.
|
|
48
|
-
"unbuild": "3.
|
|
46
|
+
"h3": "1.13.1",
|
|
47
|
+
"typescript": "5.7.3",
|
|
48
|
+
"unbuild": "3.3.1",
|
|
49
49
|
"vitest": "2.1.8"
|
|
50
50
|
},
|
|
51
51
|
"volta": {
|
|
52
|
-
"node": "22.
|
|
52
|
+
"node": "22.13.0"
|
|
53
53
|
}
|
|
54
54
|
}
|