@scayle/h3-session 0.4.2 → 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.
- package/CHANGELOG.md +11 -0
- package/dist/index.d.mts +11 -6
- package/dist/index.d.ts +11 -6
- package/dist/index.mjs +24 -21
- package/package.json +9 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @scayle/h3-session
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Cookie metadata is no longer saved in the session store. Previously, `h3-session` stored a copy of the cookie settings in the session store alongside the session data. This has been changed and now only the session data itself is stored. The cookie settings can still be read and manipulated from the `Session` object.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Removed dependency `zod@^3.23.8`
|
|
12
|
+
- Replace regex used for cookie parsing
|
|
13
|
+
|
|
3
14
|
## 0.4.2
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
|
@@ -41,7 +41,7 @@ declare class UnstorageSessionStore implements SessionStore {
|
|
|
41
41
|
* Get the session with the specified session ID
|
|
42
42
|
* @param sid the un-prefixed session ID
|
|
43
43
|
*/
|
|
44
|
-
get(sid: string): Promise<
|
|
44
|
+
get(sid: string): Promise<SessionDataT | undefined>;
|
|
45
45
|
/**
|
|
46
46
|
* Save the session with the specified session ID
|
|
47
47
|
* If the session has expired (has a TTL <= 0) it is deleted.
|
|
@@ -62,7 +62,7 @@ declare class UnstorageSessionStore implements SessionStore {
|
|
|
62
62
|
/**
|
|
63
63
|
* Fetch all saved sessions.
|
|
64
64
|
*/
|
|
65
|
-
all(): Promise<
|
|
65
|
+
all(): Promise<SessionDataT[]>;
|
|
66
66
|
/**
|
|
67
67
|
* Returns the number of saved sessions
|
|
68
68
|
*/
|
|
@@ -84,9 +84,7 @@ type SessionCookie = SessionCookieOptions & {
|
|
|
84
84
|
};
|
|
85
85
|
interface SessionDataT {
|
|
86
86
|
}
|
|
87
|
-
type RawSession = SessionDataT
|
|
88
|
-
cookie?: SessionCookieOptions;
|
|
89
|
-
};
|
|
87
|
+
type RawSession = SessionDataT;
|
|
90
88
|
interface SessionStore {
|
|
91
89
|
all?: () => Promise<RawSession[]>;
|
|
92
90
|
destroy: (sid: string) => Promise<void>;
|
|
@@ -128,6 +126,13 @@ declare module 'h3' {
|
|
|
128
126
|
* @param secrets an array of secret strings to verify with
|
|
129
127
|
*/
|
|
130
128
|
declare function unsignCookie(value: string, secrets: string[]): Promise<string | false>;
|
|
129
|
+
/**
|
|
130
|
+
* Creates a signed cookie value in the format `s:[value].[signature]`
|
|
131
|
+
* @param value
|
|
132
|
+
* @param secret
|
|
133
|
+
*/
|
|
134
|
+
declare function signCookie(value: string, secret: string): Promise<string>;
|
|
135
|
+
declare function validateConfig(config: H3SessionOptions): void;
|
|
131
136
|
/**
|
|
132
137
|
* Attach a session to an H3Event
|
|
133
138
|
* @param event
|
|
@@ -135,4 +140,4 @@ declare function unsignCookie(value: string, secrets: string[]): Promise<string
|
|
|
135
140
|
*/
|
|
136
141
|
declare function useSession(event: H3Event, config: H3SessionOptions): Promise<void>;
|
|
137
142
|
|
|
138
|
-
export { type RawSession, Session, type SessionCookie, type SessionCookieOptions, type SessionDataT, type SessionMethods, type SessionStore, UnstorageSessionStore, unsignCookie, useSession };
|
|
143
|
+
export { type H3SessionOptions, type RawSession, Session, type SessionCookie, type SessionCookieOptions, type SessionDataT, type SessionMethods, type SessionStore, UnstorageSessionStore, signCookie, unsignCookie, useSession, validateConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ declare class UnstorageSessionStore implements SessionStore {
|
|
|
41
41
|
* Get the session with the specified session ID
|
|
42
42
|
* @param sid the un-prefixed session ID
|
|
43
43
|
*/
|
|
44
|
-
get(sid: string): Promise<
|
|
44
|
+
get(sid: string): Promise<SessionDataT | undefined>;
|
|
45
45
|
/**
|
|
46
46
|
* Save the session with the specified session ID
|
|
47
47
|
* If the session has expired (has a TTL <= 0) it is deleted.
|
|
@@ -62,7 +62,7 @@ declare class UnstorageSessionStore implements SessionStore {
|
|
|
62
62
|
/**
|
|
63
63
|
* Fetch all saved sessions.
|
|
64
64
|
*/
|
|
65
|
-
all(): Promise<
|
|
65
|
+
all(): Promise<SessionDataT[]>;
|
|
66
66
|
/**
|
|
67
67
|
* Returns the number of saved sessions
|
|
68
68
|
*/
|
|
@@ -84,9 +84,7 @@ type SessionCookie = SessionCookieOptions & {
|
|
|
84
84
|
};
|
|
85
85
|
interface SessionDataT {
|
|
86
86
|
}
|
|
87
|
-
type RawSession = SessionDataT
|
|
88
|
-
cookie?: SessionCookieOptions;
|
|
89
|
-
};
|
|
87
|
+
type RawSession = SessionDataT;
|
|
90
88
|
interface SessionStore {
|
|
91
89
|
all?: () => Promise<RawSession[]>;
|
|
92
90
|
destroy: (sid: string) => Promise<void>;
|
|
@@ -128,6 +126,13 @@ declare module 'h3' {
|
|
|
128
126
|
* @param secrets an array of secret strings to verify with
|
|
129
127
|
*/
|
|
130
128
|
declare function unsignCookie(value: string, secrets: string[]): Promise<string | false>;
|
|
129
|
+
/**
|
|
130
|
+
* Creates a signed cookie value in the format `s:[value].[signature]`
|
|
131
|
+
* @param value
|
|
132
|
+
* @param secret
|
|
133
|
+
*/
|
|
134
|
+
declare function signCookie(value: string, secret: string): Promise<string>;
|
|
135
|
+
declare function validateConfig(config: H3SessionOptions): void;
|
|
131
136
|
/**
|
|
132
137
|
* Attach a session to an H3Event
|
|
133
138
|
* @param event
|
|
@@ -135,4 +140,4 @@ declare function unsignCookie(value: string, secrets: string[]): Promise<string
|
|
|
135
140
|
*/
|
|
136
141
|
declare function useSession(event: H3Event, config: H3SessionOptions): Promise<void>;
|
|
137
142
|
|
|
138
|
-
export { type RawSession, Session, type SessionCookie, type SessionCookieOptions, type SessionDataT, type SessionMethods, type SessionStore, UnstorageSessionStore, unsignCookie, useSession };
|
|
143
|
+
export { type H3SessionOptions, type RawSession, Session, type SessionCookie, type SessionCookieOptions, type SessionDataT, type SessionMethods, type SessionStore, UnstorageSessionStore, signCookie, unsignCookie, useSession, validateConfig };
|
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,6 @@ import { Buffer } from 'node:buffer';
|
|
|
2
2
|
import { getCookie, setCookie } from 'h3';
|
|
3
3
|
import { defu } from 'defu';
|
|
4
4
|
import { subtle, randomUUID } from 'uncrypto';
|
|
5
|
-
import { z } from 'zod';
|
|
6
5
|
|
|
7
6
|
class Session {
|
|
8
7
|
#id;
|
|
@@ -21,7 +20,7 @@ class Session {
|
|
|
21
20
|
return this.#id;
|
|
22
21
|
}
|
|
23
22
|
async save() {
|
|
24
|
-
await this.#store.set(this.#id,
|
|
23
|
+
await this.#store.set(this.#id, this.data);
|
|
25
24
|
}
|
|
26
25
|
async reload() {
|
|
27
26
|
this.data = await this.#store.get(this.#id) ?? (await this.#generate()).data;
|
|
@@ -39,15 +38,6 @@ class Session {
|
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
40
|
|
|
42
|
-
const CookieSchema = z.object({
|
|
43
|
-
domain: z.string().optional(),
|
|
44
|
-
expires: z.coerce.date().optional(),
|
|
45
|
-
httpOnly: z.boolean().optional(),
|
|
46
|
-
maxAge: z.number().optional(),
|
|
47
|
-
path: z.string().optional(),
|
|
48
|
-
sameSite: z.enum(["lax", "none", "strict"]).or(z.boolean()).optional(),
|
|
49
|
-
secure: z.boolean().optional()
|
|
50
|
-
});
|
|
51
41
|
class UnstorageSessionStore {
|
|
52
42
|
storage;
|
|
53
43
|
prefix;
|
|
@@ -70,13 +60,6 @@ class UnstorageSessionStore {
|
|
|
70
60
|
*/
|
|
71
61
|
async get(sid) {
|
|
72
62
|
const item = await this.storage.getItem(this.getKey(sid));
|
|
73
|
-
if (item && item.cookie) {
|
|
74
|
-
try {
|
|
75
|
-
item.cookie = CookieSchema.parse(item.cookie);
|
|
76
|
-
} catch {
|
|
77
|
-
delete item.cookie;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
63
|
return item ?? void 0;
|
|
81
64
|
}
|
|
82
65
|
/**
|
|
@@ -144,12 +127,26 @@ class UnstorageSessionStore {
|
|
|
144
127
|
}
|
|
145
128
|
}
|
|
146
129
|
|
|
130
|
+
const signatureLength = 43;
|
|
131
|
+
function parseCookieValue(value) {
|
|
132
|
+
if (value.length < signatureLength + 3) {
|
|
133
|
+
return void 0;
|
|
134
|
+
}
|
|
135
|
+
const separatorIndex = value.length - signatureLength - 1;
|
|
136
|
+
if (value.charAt(0) !== "s" || value.charAt(1) !== ":" || value.charAt(separatorIndex) !== ".") {
|
|
137
|
+
return void 0;
|
|
138
|
+
}
|
|
139
|
+
return [
|
|
140
|
+
value.substring(2, separatorIndex),
|
|
141
|
+
value.substring(separatorIndex + 1)
|
|
142
|
+
];
|
|
143
|
+
}
|
|
147
144
|
async function unsignCookie(value, secrets) {
|
|
148
|
-
const matches =
|
|
145
|
+
const matches = parseCookieValue(value);
|
|
149
146
|
if (!matches) {
|
|
150
147
|
return false;
|
|
151
148
|
}
|
|
152
|
-
const [
|
|
149
|
+
const [message, signature] = matches;
|
|
153
150
|
const encoder = new TextEncoder();
|
|
154
151
|
const messageUint8Array = encoder.encode(message);
|
|
155
152
|
const signatureUint8Array = Uint8Array.from(Buffer.from(signature, "base64"));
|
|
@@ -175,6 +172,12 @@ async function unsignCookie(value, secrets) {
|
|
|
175
172
|
return false;
|
|
176
173
|
}
|
|
177
174
|
async function signCookie(value, secret) {
|
|
175
|
+
if (!value) {
|
|
176
|
+
throw new Error("[h3-session] No value was provided!");
|
|
177
|
+
}
|
|
178
|
+
if (!secret) {
|
|
179
|
+
throw new Error("[h3-session] No secret was provided!");
|
|
180
|
+
}
|
|
178
181
|
const encoder = new TextEncoder();
|
|
179
182
|
const messageUint8Array = encoder.encode(value);
|
|
180
183
|
const keyUint8Array = encoder.encode(secret);
|
|
@@ -273,4 +276,4 @@ async function useSession(event, config) {
|
|
|
273
276
|
event.context.sessionStore = store;
|
|
274
277
|
}
|
|
275
278
|
|
|
276
|
-
export { Session, UnstorageSessionStore, unsignCookie, useSession };
|
|
279
|
+
export { Session, UnstorageSessionStore, signCookie, unsignCookie, useSession, validateConfig };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scayle/h3-session",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Persistent sessions for h3",
|
|
5
5
|
"author": "SCAYLE Commerce Engine",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,7 +22,11 @@
|
|
|
22
22
|
"format": "dprint check",
|
|
23
23
|
"format:fix": "dprint fmt",
|
|
24
24
|
"lint": "eslint . --format gitlab",
|
|
25
|
-
"lint:fix": "eslint . --fix"
|
|
25
|
+
"lint:fix": "eslint . --fix",
|
|
26
|
+
"test": "vitest run",
|
|
27
|
+
"test:ci": "vitest --run --coverage --reporter=default --reporter=junit --outputFile=./junit.xml",
|
|
28
|
+
"test:watch": "vitest watch",
|
|
29
|
+
"typecheck": "tsc --noEmit -p tsconfig.json"
|
|
26
30
|
},
|
|
27
31
|
"peerDependencies": {
|
|
28
32
|
"h3": "^1.10.0"
|
|
@@ -30,8 +34,7 @@
|
|
|
30
34
|
"dependencies": {
|
|
31
35
|
"defu": "^6.1.4",
|
|
32
36
|
"uncrypto": "^0.1.3",
|
|
33
|
-
"unstorage": "^1.10.2"
|
|
34
|
-
"zod": "^3.23.8"
|
|
37
|
+
"unstorage": "^1.10.2"
|
|
35
38
|
},
|
|
36
39
|
"devDependencies": {
|
|
37
40
|
"@arethetypeswrong/cli": "0.17.1",
|
|
@@ -41,7 +44,8 @@
|
|
|
41
44
|
"eslint-formatter-gitlab": "5.1.0",
|
|
42
45
|
"h3": "1.13.0",
|
|
43
46
|
"typescript": "5.6.3",
|
|
44
|
-
"unbuild": "3.0.1"
|
|
47
|
+
"unbuild": "3.0.1",
|
|
48
|
+
"vitest": "2.1.8"
|
|
45
49
|
},
|
|
46
50
|
"volta": {
|
|
47
51
|
"node": "22.12.0"
|