@eggjs/cookies 4.0.0-beta.20 → 4.0.0-beta.21

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.
@@ -0,0 +1,66 @@
1
+ export interface CookieSetOptions {
2
+ /**
3
+ * The path for the cookie to be set in
4
+ */
5
+ path?: string | null;
6
+ /**
7
+ * The domain for the cookie
8
+ */
9
+ domain?: string | (() => string);
10
+ /**
11
+ * Is overridable
12
+ */
13
+ overwrite?: boolean;
14
+ /**
15
+ * Is the same site
16
+ */
17
+ sameSite?: string | boolean;
18
+ /**
19
+ * Encrypt the cookie's value or not
20
+ */
21
+ encrypt?: boolean;
22
+ /**
23
+ * Max age for browsers
24
+ */
25
+ maxAge?: number;
26
+ /**
27
+ * Expire time
28
+ */
29
+ expires?: Date;
30
+ /**
31
+ * Is for http only
32
+ */
33
+ httpOnly?: boolean;
34
+ /**
35
+ * Encrypt the cookie's value or not
36
+ */
37
+ secure?: boolean;
38
+ /**
39
+ * Once `true` and secure set to `true`, ignore the secure error in a none-ssl environment.
40
+ */
41
+ ignoreSecureError?: boolean;
42
+ /**
43
+ * Is it signed or not.
44
+ */
45
+ signed?: boolean | number;
46
+ /**
47
+ * Is it partitioned or not.
48
+ */
49
+ partitioned?: boolean;
50
+ /**
51
+ * Remove unpartitioned same name cookie or not.
52
+ */
53
+ removeUnpartitioned?: boolean;
54
+ /**
55
+ * The cookie priority.
56
+ */
57
+ priority?: 'low' | 'medium' | 'high' | 'LOW' | 'MEDIUM' | 'HIGH';
58
+ }
59
+ export declare class Cookie {
60
+ name: string;
61
+ value: string;
62
+ readonly attrs: CookieSetOptions;
63
+ constructor(name: string, value?: string | null, attrs?: CookieSetOptions);
64
+ toString(): string;
65
+ toHeader(): string;
66
+ }
package/dist/cookie.js ADDED
@@ -0,0 +1,94 @@
1
+ import assert from 'node:assert';
2
+ /**
3
+ * RegExp to match field-content in RFC 7230 sec 3.2
4
+ *
5
+ * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
6
+ * field-vchar = VCHAR / obs-text
7
+ * obs-text = %x80-FF
8
+ */
9
+ const fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/; // eslint-disable-line no-control-regex
10
+ /**
11
+ * RegExp to match Same-Site cookie attribute value.
12
+ * https://en.wikipedia.org/wiki/HTTP_cookie#SameSite_cookie
13
+ */
14
+ const sameSiteRegExp = /^(?:none|lax|strict)$/i;
15
+ /**
16
+ * RegExp to match Priority cookie attribute value.
17
+ */
18
+ const PRIORITY_REGEXP = /^(?:low|medium|high)$/i;
19
+ export class Cookie {
20
+ name;
21
+ value;
22
+ attrs;
23
+ constructor(name, value, attrs) {
24
+ assert(fieldContentRegExp.test(name), 'argument name is invalid');
25
+ assert(!value || fieldContentRegExp.test(value), 'argument value is invalid');
26
+ this.name = name;
27
+ this.value = value ?? '';
28
+ this.attrs = mergeDefaultAttrs(attrs);
29
+ assert(!this.attrs.path || fieldContentRegExp.test(this.attrs.path), 'argument option path is invalid');
30
+ if (typeof this.attrs.domain === 'function') {
31
+ this.attrs.domain = this.attrs.domain();
32
+ }
33
+ assert(!this.attrs.domain || fieldContentRegExp.test(this.attrs.domain), 'argument option domain is invalid');
34
+ assert(!this.attrs.sameSite || this.attrs.sameSite === true || sameSiteRegExp.test(this.attrs.sameSite), 'argument option sameSite is invalid');
35
+ assert(!this.attrs.priority || PRIORITY_REGEXP.test(this.attrs.priority), 'argument option priority is invalid');
36
+ if (!value) {
37
+ this.attrs.expires = new Date(0);
38
+ // make sure maxAge is empty
39
+ this.attrs.maxAge = undefined;
40
+ }
41
+ }
42
+ toString() {
43
+ return this.name + '=' + this.value;
44
+ }
45
+ toHeader() {
46
+ let header = this.toString();
47
+ const attrs = this.attrs;
48
+ if (attrs.path) {
49
+ header += '; path=' + attrs.path;
50
+ }
51
+ const maxAge = typeof attrs.maxAge === 'string' ? parseInt(attrs.maxAge, 10) : attrs.maxAge;
52
+ // ignore 0, `session` and other invalid maxAge
53
+ if (maxAge) {
54
+ header += '; max-age=' + Math.round(maxAge / 1000);
55
+ attrs.expires = new Date(Date.now() + maxAge);
56
+ }
57
+ if (attrs.expires) {
58
+ header += '; expires=' + attrs.expires.toUTCString();
59
+ }
60
+ if (attrs.domain) {
61
+ header += '; domain=' + attrs.domain;
62
+ }
63
+ if (attrs.priority) {
64
+ header += '; priority=' + attrs.priority.toLowerCase();
65
+ }
66
+ if (attrs.sameSite) {
67
+ header += '; samesite=' + (attrs.sameSite === true ? 'strict' : attrs.sameSite.toLowerCase());
68
+ }
69
+ if (attrs.secure) {
70
+ header += '; secure';
71
+ }
72
+ if (attrs.httpOnly) {
73
+ header += '; httponly';
74
+ }
75
+ if (attrs.partitioned) {
76
+ header += '; partitioned';
77
+ }
78
+ return header;
79
+ }
80
+ }
81
+ function mergeDefaultAttrs(attrs) {
82
+ const merged = {
83
+ path: '/',
84
+ httpOnly: true,
85
+ secure: false,
86
+ overwrite: false,
87
+ sameSite: false,
88
+ partitioned: false,
89
+ priority: undefined,
90
+ ...attrs,
91
+ };
92
+ return merged;
93
+ }
94
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29va2llLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Nvb2tpZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFFakM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxrQkFBa0IsR0FBRyx1Q0FBdUMsQ0FBQyxDQUFDLHVDQUF1QztBQUUzRzs7O0dBR0c7QUFDSCxNQUFNLGNBQWMsR0FBRyx3QkFBd0IsQ0FBQztBQUVoRDs7R0FFRztBQUNILE1BQU0sZUFBZSxHQUFHLHdCQUF3QixDQUFDO0FBOERqRCxNQUFNLE9BQU8sTUFBTTtJQUNqQixJQUFJLENBQVM7SUFDYixLQUFLLENBQVM7SUFDTCxLQUFLLENBQW1CO0lBRWpDLFlBQVksSUFBWSxFQUFFLEtBQXFCLEVBQUUsS0FBd0I7UUFDdkUsTUFBTSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSwwQkFBMEIsQ0FBQyxDQUFDO1FBQ2xFLE1BQU0sQ0FBQyxDQUFDLEtBQUssSUFBSSxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsMkJBQTJCLENBQUMsQ0FBQztRQUM5RSxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssSUFBSSxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLEtBQUssR0FBRyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0QyxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxpQ0FBaUMsQ0FBQyxDQUFDO1FBQ3hHLElBQUksT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUM1QyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FB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
@@ -0,0 +1,43 @@
1
+ import { Keygrip } from './keygrip.ts';
2
+ import { type CookieSetOptions } from './cookie.ts';
3
+ export interface DefaultCookieOptions extends CookieSetOptions {
4
+ /**
5
+ * Auto get and set `_CHIPS-` prefix cookie to adaptation CHIPS mode (The default value is false).
6
+ */
7
+ autoChips?: boolean;
8
+ }
9
+ export interface CookieGetOptions {
10
+ /**
11
+ * Whether to sign or not (The default value is true).
12
+ */
13
+ signed?: boolean;
14
+ /**
15
+ * Encrypt the cookie's value or not (The default value is false).
16
+ */
17
+ encrypt?: boolean;
18
+ }
19
+ /**
20
+ * cookies for egg
21
+ * extend pillarjs/cookies, add encrypt and decrypt
22
+ */
23
+ export declare class Cookies {
24
+ #private;
25
+ readonly ctx: Record<string, any>;
26
+ readonly app: Record<string, any>;
27
+ readonly secure: boolean;
28
+ constructor(ctx: Record<string, any>, keys: string[], defaultCookieOptions?: DefaultCookieOptions);
29
+ get keys(): Keygrip;
30
+ /**
31
+ * get cookie value by name
32
+ * @param {String} name - cookie's name
33
+ * @param {Object} opts - cookies' options
34
+ * - {Boolean} signed - default to true
35
+ * - {Boolean} encrypt - default to false
36
+ * @return {String} value - cookie's value
37
+ */
38
+ get(name: string, opts?: CookieGetOptions): string | undefined;
39
+ _get(name: string, opts: CookieGetOptions): string | undefined;
40
+ set(name: string, value: string | null, opts?: CookieSetOptions): this;
41
+ isSameSiteNoneCompatible(userAgent: string): boolean;
42
+ isPartitionedCompatible(userAgent: string): boolean;
43
+ }
@@ -0,0 +1,287 @@
1
+ import assert from 'node:assert';
2
+ import { base64decode, base64encode } from 'utility';
3
+ import { isSameSiteNoneCompatible } from 'should-send-same-site-none';
4
+ import { Keygrip } from "./keygrip.js";
5
+ import { Cookie } from "./cookie.js";
6
+ import { CookieError } from "./error.js";
7
+ const keyCache = new Map();
8
+ /**
9
+ * cookies for egg
10
+ * extend pillarjs/cookies, add encrypt and decrypt
11
+ */
12
+ export class Cookies {
13
+ #keysArray;
14
+ #keys;
15
+ #defaultCookieOptions;
16
+ #autoChips;
17
+ ctx;
18
+ app;
19
+ secure;
20
+ #parseChromiumResult;
21
+ constructor(ctx, keys, defaultCookieOptions) {
22
+ this.#keysArray = keys;
23
+ // default cookie options
24
+ this.#defaultCookieOptions = defaultCookieOptions;
25
+ this.#autoChips = defaultCookieOptions?.autoChips;
26
+ this.ctx = ctx;
27
+ this.secure = this.ctx.secure;
28
+ this.app = ctx.app;
29
+ }
30
+ get keys() {
31
+ if (!this.#keys) {
32
+ assert(Array.isArray(this.#keysArray), '.keys required for encrypt/sign cookies');
33
+ const cache = keyCache.get(this.#keysArray);
34
+ if (cache) {
35
+ this.#keys = cache;
36
+ }
37
+ else {
38
+ this.#keys = new Keygrip(this.#keysArray);
39
+ keyCache.set(this.#keysArray, this.#keys);
40
+ }
41
+ }
42
+ return this.#keys;
43
+ }
44
+ /**
45
+ * get cookie value by name
46
+ * @param {String} name - cookie's name
47
+ * @param {Object} opts - cookies' options
48
+ * - {Boolean} signed - default to true
49
+ * - {Boolean} encrypt - default to false
50
+ * @return {String} value - cookie's value
51
+ */
52
+ get(name, opts = {}) {
53
+ let value = this._get(name, opts);
54
+ if (value === undefined && this.#autoChips) {
55
+ // try to read _CHIPS-${name} prefix cookie
56
+ value = this._get(this.#formatChipsCookieName(name), opts);
57
+ }
58
+ return value;
59
+ }
60
+ _get(name, opts) {
61
+ const signed = computeSigned(opts);
62
+ const header = this.ctx.get('cookie');
63
+ if (!header)
64
+ return;
65
+ const match = header.match(getPattern(name));
66
+ if (!match)
67
+ return;
68
+ let value = match[1];
69
+ if (!opts.encrypt && !signed)
70
+ return value;
71
+ // signed
72
+ if (signed) {
73
+ const sigName = name + '.sig';
74
+ const sigValue = this.get(sigName, { signed: false });
75
+ if (!sigValue)
76
+ return;
77
+ const raw = name + '=' + value;
78
+ const index = this.keys.verify(raw, sigValue);
79
+ if (index < 0) {
80
+ // can not match any key, remove ${name}.sig
81
+ this.set(sigName, null, { path: '/', signed: false, overwrite: true });
82
+ return;
83
+ }
84
+ if (index > 0) {
85
+ // not signed by the first key, update sigValue
86
+ this.set(sigName, this.keys.sign(raw), { signed: false, overwrite: true });
87
+ }
88
+ return value;
89
+ }
90
+ // encrypt
91
+ value = base64decode(value, true, 'buffer');
92
+ const res = this.keys.decrypt(value);
93
+ return res ? res.value.toString() : undefined;
94
+ }
95
+ set(name, value, opts) {
96
+ opts = {
97
+ ...this.#defaultCookieOptions,
98
+ ...opts,
99
+ };
100
+ const signed = computeSigned(opts);
101
+ const shouldIgnoreSecureError = opts && opts.ignoreSecureError;
102
+ value = value || '';
103
+ if (!shouldIgnoreSecureError) {
104
+ if (!this.secure && opts.secure) {
105
+ throw new CookieError('Cannot send secure cookie over unencrypted connection');
106
+ }
107
+ }
108
+ let headers = this.ctx.response.get('set-cookie') || [];
109
+ if (!Array.isArray(headers)) {
110
+ headers = [headers];
111
+ }
112
+ // encrypt
113
+ if (opts.encrypt) {
114
+ value = value && base64encode(this.keys.encrypt(value), true);
115
+ }
116
+ // http://browsercookielimits.squawky.net/
117
+ if (value.length > 4093) {
118
+ this.app.emit('cookieLimitExceed', { name, value, ctx: this.ctx });
119
+ }
120
+ // https://github.com/linsight/should-send-same-site-none
121
+ // fixed SameSite=None: Known Incompatible Clients
122
+ const userAgent = this.ctx.get('user-agent');
123
+ let isSameSiteNone = false;
124
+ // disable autoChips if partitioned enable
125
+ let autoChips = !opts.partitioned && this.#autoChips;
126
+ if (opts.sameSite && typeof opts.sameSite === 'string' && opts.sameSite.toLowerCase() === 'none') {
127
+ isSameSiteNone = true;
128
+ if (opts.secure === false || !this.secure || (userAgent && !this.isSameSiteNoneCompatible(userAgent))) {
129
+ // Non-secure context or Incompatible clients, don't send SameSite=None property
130
+ opts.sameSite = false;
131
+ isSameSiteNone = false;
132
+ }
133
+ }
134
+ if (autoChips || opts.partitioned) {
135
+ // allow to set partitioned: secure=true and sameSite=none and chrome >= 118
136
+ if (!isSameSiteNone ||
137
+ opts.secure === false ||
138
+ !this.secure ||
139
+ (userAgent && !this.isPartitionedCompatible(userAgent))) {
140
+ // Non-secure context or Incompatible clients, don't send partitioned property
141
+ autoChips = false;
142
+ opts.partitioned = false;
143
+ }
144
+ }
145
+ // remove unpartitioned same name cookie first
146
+ if (opts.partitioned && opts.removeUnpartitioned) {
147
+ const overwrite = opts.overwrite;
148
+ if (overwrite) {
149
+ opts.overwrite = false;
150
+ headers = ignoreCookiesByName(headers, name);
151
+ }
152
+ const removeCookieOpts = {
153
+ ...opts,
154
+ partitioned: false,
155
+ };
156
+ const removeUnpartitionedCookie = new Cookie(name, '', removeCookieOpts);
157
+ // if user not set secure, reset secure to ctx.secure
158
+ if (opts.secure === undefined) {
159
+ removeUnpartitionedCookie.attrs.secure = this.secure;
160
+ }
161
+ headers = pushCookie(headers, removeUnpartitionedCookie);
162
+ // signed
163
+ if (signed) {
164
+ removeUnpartitionedCookie.name += '.sig';
165
+ headers = ignoreCookiesByNameAndPath(headers, removeUnpartitionedCookie.name, removeUnpartitionedCookie.attrs.path);
166
+ headers = pushCookie(headers, removeUnpartitionedCookie);
167
+ }
168
+ }
169
+ else if (autoChips) {
170
+ // add _CHIPS-${name} prefix cookie
171
+ const newCookieName = this.#formatChipsCookieName(name);
172
+ const newCookieOpts = {
173
+ ...opts,
174
+ partitioned: true,
175
+ };
176
+ const newPartitionedCookie = new Cookie(newCookieName, value, newCookieOpts);
177
+ // if user not set secure, reset secure to ctx.secure
178
+ if (opts.secure === undefined)
179
+ newPartitionedCookie.attrs.secure = this.secure;
180
+ headers = pushCookie(headers, newPartitionedCookie);
181
+ // signed
182
+ if (signed) {
183
+ newPartitionedCookie.value = value && this.keys.sign(newPartitionedCookie.toString());
184
+ newPartitionedCookie.name += '.sig';
185
+ headers = ignoreCookiesByNameAndPath(headers, newPartitionedCookie.name, newPartitionedCookie.attrs.path);
186
+ headers = pushCookie(headers, newPartitionedCookie);
187
+ }
188
+ }
189
+ const cookie = new Cookie(name, value, opts);
190
+ // if user not set secure, reset secure to ctx.secure
191
+ if (opts.secure === undefined) {
192
+ cookie.attrs.secure = this.secure;
193
+ }
194
+ headers = pushCookie(headers, cookie);
195
+ // signed
196
+ if (signed) {
197
+ cookie.value = value && this.keys.sign(cookie.toString());
198
+ cookie.name += '.sig';
199
+ headers = pushCookie(headers, cookie);
200
+ }
201
+ this.ctx.set('set-cookie', headers);
202
+ return this;
203
+ }
204
+ #formatChipsCookieName(name) {
205
+ return `_CHIPS-${name}`;
206
+ }
207
+ #parseChromiumAndMajorVersion(userAgent) {
208
+ if (!this.#parseChromiumResult) {
209
+ this.#parseChromiumResult = parseChromiumAndMajorVersion(userAgent);
210
+ }
211
+ return this.#parseChromiumResult;
212
+ }
213
+ isSameSiteNoneCompatible(userAgent) {
214
+ // Chrome >= 80.0.0.0
215
+ const result = this.#parseChromiumAndMajorVersion(userAgent);
216
+ if (result.chromium) {
217
+ return result.majorVersion >= 80;
218
+ }
219
+ return isSameSiteNoneCompatible(userAgent);
220
+ }
221
+ isPartitionedCompatible(userAgent) {
222
+ // support: Chrome >= 114.0.0.0
223
+ // default enable: Chrome >= 118.0.0.0
224
+ // https://developers.google.com/privacy-sandbox/3pcd/chips
225
+ const result = this.#parseChromiumAndMajorVersion(userAgent);
226
+ if (result.chromium) {
227
+ return result.majorVersion >= 118;
228
+ }
229
+ return false;
230
+ }
231
+ }
232
+ // https://github.com/linsight/should-send-same-site-none/blob/master/index.js#L86
233
+ function parseChromiumAndMajorVersion(userAgent) {
234
+ const m = /Chrom[^ /]{1,100}\/(\d{1,100}?)\./.exec(userAgent);
235
+ if (!m) {
236
+ return { chromium: false, majorVersion: 0 };
237
+ }
238
+ // Extract digits from first capturing group.
239
+ return { chromium: true, majorVersion: parseInt(m[1]) };
240
+ }
241
+ const _patternCache = new Map();
242
+ function getPattern(name) {
243
+ const cache = _patternCache.get(name);
244
+ if (cache) {
245
+ return cache;
246
+ }
247
+ const reg = new RegExp('(?:^|;) *' + name.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&') + '=([^;]*)');
248
+ _patternCache.set(name, reg);
249
+ return reg;
250
+ }
251
+ function computeSigned(opts) {
252
+ // encrypt default to false, signed default to true.
253
+ // disable singed when encrypt is true.
254
+ if (opts.encrypt)
255
+ return false;
256
+ return opts.signed !== false;
257
+ }
258
+ function pushCookie(cookies, cookie) {
259
+ if (cookie.attrs.overwrite) {
260
+ cookies = ignoreCookiesByName(cookies, cookie.name);
261
+ }
262
+ cookies.push(cookie.toHeader());
263
+ return cookies;
264
+ }
265
+ function ignoreCookiesByName(cookies, name) {
266
+ const prefix = `${name}=`;
267
+ return cookies.filter(c => !c.startsWith(prefix));
268
+ }
269
+ function ignoreCookiesByNameAndPath(cookies, name, path) {
270
+ if (!path) {
271
+ return ignoreCookiesByName(cookies, name);
272
+ }
273
+ const prefix = `${name}=`;
274
+ // foo=hello; path=/path1; samesite=none
275
+ const includedPath = `; path=${path};`;
276
+ // foo=hello; path=/path1
277
+ const endsWithPath = `; path=${path}`;
278
+ return cookies.filter(c => {
279
+ if (c.startsWith(prefix)) {
280
+ if (c.includes(includedPath) || c.endsWith(endsWithPath)) {
281
+ return false;
282
+ }
283
+ }
284
+ return true;
285
+ });
286
+ }
287
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29va2llcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb29raWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sTUFBTSxNQUFNLGFBQWEsQ0FBQztBQUVqQyxPQUFPLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNyRCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUV0RSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxNQUFNLEVBQXlCLE1BQU0sYUFBYSxDQUFDO0FBQzVELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFekMsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQXFCLENBQUM7QUFvQjlDOzs7R0FHRztBQUNILE1BQU0sT0FBTyxPQUFPO0lBQ1QsVUFBVSxDQUFXO0lBQzlCLEtBQUssQ0FBVTtJQUNOLHFCQUFxQixDQUF3QjtJQUM3QyxVQUFVLENBQVc7SUFDckIsR0FBRyxDQUFzQjtJQUN6QixHQUFHLENBQXNCO0lBQ3pCLE1BQU0sQ0FBVTtJQUN6QixvQkFBb0IsQ0FBdUI7SUFFM0MsWUFBWSxHQUF3QixFQUFFLElBQWMsRUFBRSxvQkFBMkM7UUFDL0YsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFDdkIseUJBQXlCO1FBQ3pCLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxvQkFBb0IsQ0FBQztRQUNsRCxJQUFJLENBQUMsVUFBVSxHQUFHLG9CQUFvQixFQUFFLFNBQVMsQ0FBQztRQUNsRCxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNmLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUM7UUFDOUIsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxJQUFJLElB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
@@ -0,0 +1,3 @@
1
+ export declare class CookieError extends Error {
2
+ constructor(message: string, options?: ErrorOptions);
3
+ }
package/dist/error.js ADDED
@@ -0,0 +1,10 @@
1
+ export class CookieError extends Error {
2
+ constructor(message, options) {
3
+ super(message, options);
4
+ this.name = this.constructor.name;
5
+ if ('captureStackTrace' in Error) {
6
+ Error.captureStackTrace(this, this.constructor);
7
+ }
8
+ }
9
+ }
10
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZXJyb3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxPQUFPLFdBQVksU0FBUSxLQUFLO0lBQ3BDLFlBQVksT0FBZSxFQUFFLE9BQXNCO1FBQ2pELEtBQUssQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDeEIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztRQUNsQyxJQUFJLG1CQUFtQixJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ2pDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ2xELENBQUM7SUFDSCxDQUFDO0NBQ0YifQ==
package/dist/index.d.ts CHANGED
@@ -1,130 +1,4 @@
1
- //#region src/keygrip.d.ts
2
- declare class Keygrip {
3
- #private;
4
- constructor(keys: string[]);
5
- encrypt(data: string, key?: string): Buffer<ArrayBuffer>;
6
- decrypt(data: string | Buffer): {
7
- value: Buffer;
8
- index: number;
9
- } | false;
10
- sign(data: string | Buffer, key?: string): string;
11
- verify(data: string, digest: string): number;
12
- }
13
- //#endregion
14
- //#region src/cookie.d.ts
15
- interface CookieSetOptions {
16
- /**
17
- * The path for the cookie to be set in
18
- */
19
- path?: string | null;
20
- /**
21
- * The domain for the cookie
22
- */
23
- domain?: string | (() => string);
24
- /**
25
- * Is overridable
26
- */
27
- overwrite?: boolean;
28
- /**
29
- * Is the same site
30
- */
31
- sameSite?: string | boolean;
32
- /**
33
- * Encrypt the cookie's value or not
34
- */
35
- encrypt?: boolean;
36
- /**
37
- * Max age for browsers
38
- */
39
- maxAge?: number;
40
- /**
41
- * Expire time
42
- */
43
- expires?: Date;
44
- /**
45
- * Is for http only
46
- */
47
- httpOnly?: boolean;
48
- /**
49
- * Encrypt the cookie's value or not
50
- */
51
- secure?: boolean;
52
- /**
53
- * Once `true` and secure set to `true`, ignore the secure error in a none-ssl environment.
54
- */
55
- ignoreSecureError?: boolean;
56
- /**
57
- * Is it signed or not.
58
- */
59
- signed?: boolean | number;
60
- /**
61
- * Is it partitioned or not.
62
- */
63
- partitioned?: boolean;
64
- /**
65
- * Remove unpartitioned same name cookie or not.
66
- */
67
- removeUnpartitioned?: boolean;
68
- /**
69
- * The cookie priority.
70
- */
71
- priority?: 'low' | 'medium' | 'high' | 'LOW' | 'MEDIUM' | 'HIGH';
72
- }
73
- declare class Cookie {
74
- name: string;
75
- value: string;
76
- readonly attrs: CookieSetOptions;
77
- constructor(name: string, value?: string | null, attrs?: CookieSetOptions);
78
- toString(): string;
79
- toHeader(): string;
80
- }
81
- //#endregion
82
- //#region src/cookies.d.ts
83
- interface DefaultCookieOptions extends CookieSetOptions {
84
- /**
85
- * Auto get and set `_CHIPS-` prefix cookie to adaptation CHIPS mode (The default value is false).
86
- */
87
- autoChips?: boolean;
88
- }
89
- interface CookieGetOptions {
90
- /**
91
- * Whether to sign or not (The default value is true).
92
- */
93
- signed?: boolean;
94
- /**
95
- * Encrypt the cookie's value or not (The default value is false).
96
- */
97
- encrypt?: boolean;
98
- }
99
- /**
100
- * cookies for egg
101
- * extend pillarjs/cookies, add encrypt and decrypt
102
- */
103
- declare class Cookies {
104
- #private;
105
- readonly ctx: Record<string, any>;
106
- readonly app: Record<string, any>;
107
- readonly secure: boolean;
108
- constructor(ctx: Record<string, any>, keys: string[], defaultCookieOptions?: DefaultCookieOptions);
109
- get keys(): Keygrip;
110
- /**
111
- * get cookie value by name
112
- * @param {String} name - cookie's name
113
- * @param {Object} opts - cookies' options
114
- * - {Boolean} signed - default to true
115
- * - {Boolean} encrypt - default to false
116
- * @return {String} value - cookie's value
117
- */
118
- get(name: string, opts?: CookieGetOptions): string | undefined;
119
- _get(name: string, opts: CookieGetOptions): string | undefined;
120
- set(name: string, value: string | null, opts?: CookieSetOptions): this;
121
- isSameSiteNoneCompatible(userAgent: string): boolean;
122
- isPartitionedCompatible(userAgent: string): boolean;
123
- }
124
- //#endregion
125
- //#region src/error.d.ts
126
- declare class CookieError extends Error {
127
- constructor(message: string, options?: ErrorOptions);
128
- }
129
- //#endregion
130
- export { Cookie, CookieError, CookieGetOptions, CookieSetOptions, Cookies, DefaultCookieOptions, Keygrip };
1
+ export * from './cookies.ts';
2
+ export * from './cookie.ts';
3
+ export * from './error.ts';
4
+ export * from './keygrip.ts';
package/dist/index.js CHANGED
@@ -1,407 +1,5 @@
1
- import assert from "node:assert";
2
- import { base64decode, base64encode } from "utility";
3
- import { isSameSiteNoneCompatible } from "should-send-same-site-none";
4
- import { debuglog } from "node:util";
5
- import crypto from "node:crypto";
6
-
7
- //#region src/keygrip.ts
8
- const debug = debuglog("egg/cookies:keygrip");
9
- const KEY_LEN = 32;
10
- const IV_SIZE = 16;
11
- const passwordCache = /* @__PURE__ */ new Map();
12
- const replacer = {
13
- "/": "_",
14
- "+": "-",
15
- "=": ""
16
- };
17
- function constantTimeCompare(a, b) {
18
- if (a.length !== b.length) return false;
19
- return crypto.timingSafeEqual(a, b);
20
- }
21
- var Keygrip = class {
22
- #keys;
23
- #hash = "sha256";
24
- #cipher = "aes-256-cbc";
25
- constructor(keys) {
26
- assert(Array.isArray(keys) && keys.length > 0, "keys must be provided and should be an array");
27
- this.#keys = keys;
28
- }
29
- encrypt(data, key) {
30
- key = key || this.#keys[0];
31
- const password = keyToPassword(key);
32
- const cipher = crypto.createCipheriv(this.#cipher, password.key, password.iv);
33
- return crypt(cipher, data);
34
- }
35
- decrypt(data) {
36
- const keys = this.#keys;
37
- for (let i = 0; i < keys.length; i++) {
38
- const value = this.#decryptByKey(data, keys[i]);
39
- if (value !== false) return {
40
- value,
41
- index: i
42
- };
43
- }
44
- return false;
45
- }
46
- #decryptByKey(data, key) {
47
- try {
48
- const password = keyToPassword(key);
49
- const cipher = crypto.createDecipheriv(this.#cipher, password.key, password.iv);
50
- return crypt(cipher, data);
51
- } catch (err) {
52
- debug("crypt error: %s", err);
53
- return false;
54
- }
55
- }
56
- sign(data, key) {
57
- key = key || this.#keys[0];
58
- return crypto.createHmac(this.#hash, key).update(data).digest("base64").replace(/\/|\+|=/g, (x) => {
59
- return replacer[x];
60
- });
61
- }
62
- verify(data, digest) {
63
- const keys = this.#keys;
64
- for (let i = 0; i < keys.length; i++) {
65
- const key = keys[i];
66
- if (constantTimeCompare(Buffer.from(digest), Buffer.from(this.sign(data, key)))) {
67
- debug("data %s match key %s, index: %d", data, key, i);
68
- return i;
69
- }
70
- }
71
- return -1;
72
- }
73
- };
74
- function crypt(cipher, data) {
75
- const text = Buffer.isBuffer(data) ? cipher.update(data) : cipher.update(data, "utf-8");
76
- const pad = cipher.final();
77
- return Buffer.concat([text, pad]);
78
- }
79
- function keyToPassword(key) {
80
- if (passwordCache.has(key)) return passwordCache.get(key);
81
- const bytes = Buffer.alloc(KEY_LEN + IV_SIZE);
82
- let lastHash = null, nBytes = 0;
83
- while (nBytes < bytes.length) {
84
- const hash = crypto.createHash("md5");
85
- if (lastHash) hash.update(lastHash);
86
- hash.update(key);
87
- lastHash = hash.digest();
88
- lastHash.copy(bytes, nBytes);
89
- nBytes += lastHash.length;
90
- }
91
- const password = {
92
- key: bytes.subarray(0, KEY_LEN),
93
- iv: bytes.subarray(KEY_LEN, bytes.length)
94
- };
95
- passwordCache.set(key, password);
96
- return password;
97
- }
98
-
99
- //#endregion
100
- //#region src/cookie.ts
101
- /**
102
- * RegExp to match field-content in RFC 7230 sec 3.2
103
- *
104
- * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
105
- * field-vchar = VCHAR / obs-text
106
- * obs-text = %x80-FF
107
- */
108
- const fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
109
- /**
110
- * RegExp to match Same-Site cookie attribute value.
111
- * https://en.wikipedia.org/wiki/HTTP_cookie#SameSite_cookie
112
- */
113
- const sameSiteRegExp = /^(?:none|lax|strict)$/i;
114
- /**
115
- * RegExp to match Priority cookie attribute value.
116
- */
117
- const PRIORITY_REGEXP = /^(?:low|medium|high)$/i;
118
- var Cookie = class {
119
- name;
120
- value;
121
- attrs;
122
- constructor(name, value, attrs) {
123
- assert(fieldContentRegExp.test(name), "argument name is invalid");
124
- assert(!value || fieldContentRegExp.test(value), "argument value is invalid");
125
- this.name = name;
126
- this.value = value ?? "";
127
- this.attrs = mergeDefaultAttrs(attrs);
128
- assert(!this.attrs.path || fieldContentRegExp.test(this.attrs.path), "argument option path is invalid");
129
- if (typeof this.attrs.domain === "function") this.attrs.domain = this.attrs.domain();
130
- assert(!this.attrs.domain || fieldContentRegExp.test(this.attrs.domain), "argument option domain is invalid");
131
- assert(!this.attrs.sameSite || this.attrs.sameSite === true || sameSiteRegExp.test(this.attrs.sameSite), "argument option sameSite is invalid");
132
- assert(!this.attrs.priority || PRIORITY_REGEXP.test(this.attrs.priority), "argument option priority is invalid");
133
- if (!value) {
134
- this.attrs.expires = /* @__PURE__ */ new Date(0);
135
- this.attrs.maxAge = void 0;
136
- }
137
- }
138
- toString() {
139
- return this.name + "=" + this.value;
140
- }
141
- toHeader() {
142
- let header = this.toString();
143
- const attrs = this.attrs;
144
- if (attrs.path) header += "; path=" + attrs.path;
145
- const maxAge = typeof attrs.maxAge === "string" ? parseInt(attrs.maxAge, 10) : attrs.maxAge;
146
- if (maxAge) {
147
- header += "; max-age=" + Math.round(maxAge / 1e3);
148
- attrs.expires = new Date(Date.now() + maxAge);
149
- }
150
- if (attrs.expires) header += "; expires=" + attrs.expires.toUTCString();
151
- if (attrs.domain) header += "; domain=" + attrs.domain;
152
- if (attrs.priority) header += "; priority=" + attrs.priority.toLowerCase();
153
- if (attrs.sameSite) header += "; samesite=" + (attrs.sameSite === true ? "strict" : attrs.sameSite.toLowerCase());
154
- if (attrs.secure) header += "; secure";
155
- if (attrs.httpOnly) header += "; httponly";
156
- if (attrs.partitioned) header += "; partitioned";
157
- return header;
158
- }
159
- };
160
- function mergeDefaultAttrs(attrs) {
161
- return {
162
- path: "/",
163
- httpOnly: true,
164
- secure: false,
165
- overwrite: false,
166
- sameSite: false,
167
- partitioned: false,
168
- priority: void 0,
169
- ...attrs
170
- };
171
- }
172
-
173
- //#endregion
174
- //#region src/error.ts
175
- var CookieError = class extends Error {
176
- constructor(message, options) {
177
- super(message, options);
178
- this.name = this.constructor.name;
179
- if ("captureStackTrace" in Error) Error.captureStackTrace(this, this.constructor);
180
- }
181
- };
182
-
183
- //#endregion
184
- //#region src/cookies.ts
185
- const keyCache = /* @__PURE__ */ new Map();
186
- /**
187
- * cookies for egg
188
- * extend pillarjs/cookies, add encrypt and decrypt
189
- */
190
- var Cookies = class {
191
- #keysArray;
192
- #keys;
193
- #defaultCookieOptions;
194
- #autoChips;
195
- ctx;
196
- app;
197
- secure;
198
- #parseChromiumResult;
199
- constructor(ctx, keys, defaultCookieOptions) {
200
- this.#keysArray = keys;
201
- this.#defaultCookieOptions = defaultCookieOptions;
202
- this.#autoChips = defaultCookieOptions?.autoChips;
203
- this.ctx = ctx;
204
- this.secure = this.ctx.secure;
205
- this.app = ctx.app;
206
- }
207
- get keys() {
208
- if (!this.#keys) {
209
- assert(Array.isArray(this.#keysArray), ".keys required for encrypt/sign cookies");
210
- const cache = keyCache.get(this.#keysArray);
211
- if (cache) this.#keys = cache;
212
- else {
213
- this.#keys = new Keygrip(this.#keysArray);
214
- keyCache.set(this.#keysArray, this.#keys);
215
- }
216
- }
217
- return this.#keys;
218
- }
219
- /**
220
- * get cookie value by name
221
- * @param {String} name - cookie's name
222
- * @param {Object} opts - cookies' options
223
- * - {Boolean} signed - default to true
224
- * - {Boolean} encrypt - default to false
225
- * @return {String} value - cookie's value
226
- */
227
- get(name, opts = {}) {
228
- let value = this._get(name, opts);
229
- if (value === void 0 && this.#autoChips) value = this._get(this.#formatChipsCookieName(name), opts);
230
- return value;
231
- }
232
- _get(name, opts) {
233
- const signed = computeSigned(opts);
234
- const header = this.ctx.get("cookie");
235
- if (!header) return;
236
- const match = header.match(getPattern(name));
237
- if (!match) return;
238
- let value = match[1];
239
- if (!opts.encrypt && !signed) return value;
240
- if (signed) {
241
- const sigName = name + ".sig";
242
- const sigValue = this.get(sigName, { signed: false });
243
- if (!sigValue) return;
244
- const raw = name + "=" + value;
245
- const index = this.keys.verify(raw, sigValue);
246
- if (index < 0) {
247
- this.set(sigName, null, {
248
- path: "/",
249
- signed: false,
250
- overwrite: true
251
- });
252
- return;
253
- }
254
- if (index > 0) this.set(sigName, this.keys.sign(raw), {
255
- signed: false,
256
- overwrite: true
257
- });
258
- return value;
259
- }
260
- value = base64decode(value, true, "buffer");
261
- const res = this.keys.decrypt(value);
262
- return res ? res.value.toString() : void 0;
263
- }
264
- set(name, value, opts) {
265
- opts = {
266
- ...this.#defaultCookieOptions,
267
- ...opts
268
- };
269
- const signed = computeSigned(opts);
270
- const shouldIgnoreSecureError = opts && opts.ignoreSecureError;
271
- value = value || "";
272
- if (!shouldIgnoreSecureError) {
273
- if (!this.secure && opts.secure) throw new CookieError("Cannot send secure cookie over unencrypted connection");
274
- }
275
- let headers = this.ctx.response.get("set-cookie") || [];
276
- if (!Array.isArray(headers)) headers = [headers];
277
- if (opts.encrypt) value = value && base64encode(this.keys.encrypt(value), true);
278
- if (value.length > 4093) this.app.emit("cookieLimitExceed", {
279
- name,
280
- value,
281
- ctx: this.ctx
282
- });
283
- const userAgent = this.ctx.get("user-agent");
284
- let isSameSiteNone = false;
285
- let autoChips = !opts.partitioned && this.#autoChips;
286
- if (opts.sameSite && typeof opts.sameSite === "string" && opts.sameSite.toLowerCase() === "none") {
287
- isSameSiteNone = true;
288
- if (opts.secure === false || !this.secure || userAgent && !this.isSameSiteNoneCompatible(userAgent)) {
289
- opts.sameSite = false;
290
- isSameSiteNone = false;
291
- }
292
- }
293
- if (autoChips || opts.partitioned) {
294
- if (!isSameSiteNone || opts.secure === false || !this.secure || userAgent && !this.isPartitionedCompatible(userAgent)) {
295
- autoChips = false;
296
- opts.partitioned = false;
297
- }
298
- }
299
- if (opts.partitioned && opts.removeUnpartitioned) {
300
- if (opts.overwrite) {
301
- opts.overwrite = false;
302
- headers = ignoreCookiesByName(headers, name);
303
- }
304
- const removeCookieOpts = {
305
- ...opts,
306
- partitioned: false
307
- };
308
- const removeUnpartitionedCookie = new Cookie(name, "", removeCookieOpts);
309
- if (opts.secure === void 0) removeUnpartitionedCookie.attrs.secure = this.secure;
310
- headers = pushCookie(headers, removeUnpartitionedCookie);
311
- if (signed) {
312
- removeUnpartitionedCookie.name += ".sig";
313
- headers = ignoreCookiesByNameAndPath(headers, removeUnpartitionedCookie.name, removeUnpartitionedCookie.attrs.path);
314
- headers = pushCookie(headers, removeUnpartitionedCookie);
315
- }
316
- } else if (autoChips) {
317
- const newCookieName = this.#formatChipsCookieName(name);
318
- const newCookieOpts = {
319
- ...opts,
320
- partitioned: true
321
- };
322
- const newPartitionedCookie = new Cookie(newCookieName, value, newCookieOpts);
323
- if (opts.secure === void 0) newPartitionedCookie.attrs.secure = this.secure;
324
- headers = pushCookie(headers, newPartitionedCookie);
325
- if (signed) {
326
- newPartitionedCookie.value = value && this.keys.sign(newPartitionedCookie.toString());
327
- newPartitionedCookie.name += ".sig";
328
- headers = ignoreCookiesByNameAndPath(headers, newPartitionedCookie.name, newPartitionedCookie.attrs.path);
329
- headers = pushCookie(headers, newPartitionedCookie);
330
- }
331
- }
332
- const cookie = new Cookie(name, value, opts);
333
- if (opts.secure === void 0) cookie.attrs.secure = this.secure;
334
- headers = pushCookie(headers, cookie);
335
- if (signed) {
336
- cookie.value = value && this.keys.sign(cookie.toString());
337
- cookie.name += ".sig";
338
- headers = pushCookie(headers, cookie);
339
- }
340
- this.ctx.set("set-cookie", headers);
341
- return this;
342
- }
343
- #formatChipsCookieName(name) {
344
- return `_CHIPS-${name}`;
345
- }
346
- #parseChromiumAndMajorVersion(userAgent) {
347
- if (!this.#parseChromiumResult) this.#parseChromiumResult = parseChromiumAndMajorVersion(userAgent);
348
- return this.#parseChromiumResult;
349
- }
350
- isSameSiteNoneCompatible(userAgent) {
351
- const result = this.#parseChromiumAndMajorVersion(userAgent);
352
- if (result.chromium) return result.majorVersion >= 80;
353
- return isSameSiteNoneCompatible(userAgent);
354
- }
355
- isPartitionedCompatible(userAgent) {
356
- const result = this.#parseChromiumAndMajorVersion(userAgent);
357
- if (result.chromium) return result.majorVersion >= 118;
358
- return false;
359
- }
360
- };
361
- function parseChromiumAndMajorVersion(userAgent) {
362
- const m = /Chrom[^ /]{1,100}\/(\d{1,100}?)\./.exec(userAgent);
363
- if (!m) return {
364
- chromium: false,
365
- majorVersion: 0
366
- };
367
- return {
368
- chromium: true,
369
- majorVersion: parseInt(m[1])
370
- };
371
- }
372
- const _patternCache = /* @__PURE__ */ new Map();
373
- function getPattern(name) {
374
- const cache = _patternCache.get(name);
375
- if (cache) return cache;
376
- const reg = /* @__PURE__ */ new RegExp("(?:^|;) *" + name.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&") + "=([^;]*)");
377
- _patternCache.set(name, reg);
378
- return reg;
379
- }
380
- function computeSigned(opts) {
381
- if (opts.encrypt) return false;
382
- return opts.signed !== false;
383
- }
384
- function pushCookie(cookies, cookie) {
385
- if (cookie.attrs.overwrite) cookies = ignoreCookiesByName(cookies, cookie.name);
386
- cookies.push(cookie.toHeader());
387
- return cookies;
388
- }
389
- function ignoreCookiesByName(cookies, name) {
390
- const prefix = `${name}=`;
391
- return cookies.filter((c) => !c.startsWith(prefix));
392
- }
393
- function ignoreCookiesByNameAndPath(cookies, name, path) {
394
- if (!path) return ignoreCookiesByName(cookies, name);
395
- const prefix = `${name}=`;
396
- const includedPath = `; path=${path};`;
397
- const endsWithPath = `; path=${path}`;
398
- return cookies.filter((c) => {
399
- if (c.startsWith(prefix)) {
400
- if (c.includes(includedPath) || c.endsWith(endsWithPath)) return false;
401
- }
402
- return true;
403
- });
404
- }
405
-
406
- //#endregion
407
- export { Cookie, CookieError, Cookies, Keygrip };
1
+ export * from "./cookies.js";
2
+ export * from "./cookie.js";
3
+ export * from "./error.js";
4
+ export * from "./keygrip.js";
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxZQUFZLENBQUM7QUFDM0IsY0FBYyxjQUFjLENBQUMifQ==
@@ -0,0 +1,11 @@
1
+ export declare class Keygrip {
2
+ #private;
3
+ constructor(keys: string[]);
4
+ encrypt(data: string, key?: string): Buffer<ArrayBuffer>;
5
+ decrypt(data: string | Buffer): {
6
+ value: Buffer;
7
+ index: number;
8
+ } | false;
9
+ sign(data: string | Buffer, key?: string): string;
10
+ verify(data: string, digest: string): number;
11
+ }
@@ -0,0 +1,113 @@
1
+ import { debuglog } from 'node:util';
2
+ import crypto, {} from 'node:crypto';
3
+ import assert from 'node:assert';
4
+ const debug = debuglog('egg/cookies:keygrip');
5
+ const KEY_LEN = 32;
6
+ const IV_SIZE = 16;
7
+ const passwordCache = new Map();
8
+ const replacer = {
9
+ '/': '_',
10
+ '+': '-',
11
+ '=': '',
12
+ };
13
+ function constantTimeCompare(a, b) {
14
+ if (a.length !== b.length) {
15
+ return false;
16
+ }
17
+ return crypto.timingSafeEqual(a, b);
18
+ }
19
+ // patch from https://github.com/crypto-utils/keygrip
20
+ export class Keygrip {
21
+ #keys;
22
+ #hash = 'sha256';
23
+ #cipher = 'aes-256-cbc';
24
+ constructor(keys) {
25
+ assert(Array.isArray(keys) && keys.length > 0, 'keys must be provided and should be an array');
26
+ this.#keys = keys;
27
+ }
28
+ // encrypt a message
29
+ encrypt(data, key) {
30
+ key = key || this.#keys[0];
31
+ const password = keyToPassword(key);
32
+ const cipher = crypto.createCipheriv(this.#cipher, password.key, password.iv);
33
+ return crypt(cipher, data);
34
+ }
35
+ // decrypt a single message
36
+ // returns false on bad decrypts
37
+ decrypt(data) {
38
+ // decrypt every key
39
+ const keys = this.#keys;
40
+ for (let i = 0; i < keys.length; i++) {
41
+ const value = this.#decryptByKey(data, keys[i]);
42
+ if (value !== false) {
43
+ return { value, index: i };
44
+ }
45
+ }
46
+ return false;
47
+ }
48
+ #decryptByKey(data, key) {
49
+ try {
50
+ const password = keyToPassword(key);
51
+ const cipher = crypto.createDecipheriv(this.#cipher, password.key, password.iv);
52
+ return crypt(cipher, data);
53
+ }
54
+ catch (err) {
55
+ debug('crypt error: %s', err);
56
+ return false;
57
+ }
58
+ }
59
+ sign(data, key) {
60
+ // default to the first key
61
+ key = key || this.#keys[0];
62
+ // url safe base64
63
+ return crypto
64
+ .createHmac(this.#hash, key)
65
+ .update(data)
66
+ .digest('base64')
67
+ .replace(/\/|\+|=/g, x => {
68
+ return replacer[x];
69
+ });
70
+ }
71
+ verify(data, digest) {
72
+ const keys = this.#keys;
73
+ for (let i = 0; i < keys.length; i++) {
74
+ const key = keys[i];
75
+ if (constantTimeCompare(Buffer.from(digest), Buffer.from(this.sign(data, key)))) {
76
+ debug('data %s match key %s, index: %d', data, key, i);
77
+ return i;
78
+ }
79
+ }
80
+ return -1;
81
+ }
82
+ }
83
+ function crypt(cipher, data) {
84
+ const text = Buffer.isBuffer(data) ? cipher.update(data) : cipher.update(data, 'utf-8');
85
+ const pad = cipher.final();
86
+ return Buffer.concat([text, pad]);
87
+ }
88
+ function keyToPassword(key) {
89
+ if (passwordCache.has(key)) {
90
+ return passwordCache.get(key);
91
+ }
92
+ // Simulate EVP_BytesToKey.
93
+ // see https://github.com/nodejs/help/issues/1673#issuecomment-503222925
94
+ const bytes = Buffer.alloc(KEY_LEN + IV_SIZE);
95
+ let lastHash = null, nBytes = 0;
96
+ while (nBytes < bytes.length) {
97
+ const hash = crypto.createHash('md5');
98
+ if (lastHash)
99
+ hash.update(lastHash);
100
+ hash.update(key);
101
+ lastHash = hash.digest();
102
+ lastHash.copy(bytes, nBytes);
103
+ nBytes += lastHash.length;
104
+ }
105
+ // Use these for decryption.
106
+ const password = {
107
+ key: bytes.subarray(0, KEY_LEN),
108
+ iv: bytes.subarray(KEY_LEN, bytes.length),
109
+ };
110
+ passwordCache.set(key, password);
111
+ return password;
112
+ }
113
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia2V5Z3JpcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9rZXlncmlwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxNQUFNLEVBQUUsRUFBaUIsTUFBTSxhQUFhLENBQUM7QUFDcEQsT0FBTyxNQUFNLE1BQU0sYUFBYSxDQUFDO0FBRWpDLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0FBRTlDLE1BQU0sT0FBTyxHQUFHLEVBQUUsQ0FBQztBQUNuQixNQUFNLE9BQU8sR0FBRyxFQUFFLENBQUM7QUFDbkIsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQztBQUVoQyxNQUFNLFFBQVEsR0FBMkI7SUFDdkMsR0FBRyxFQUFFLEdBQUc7SUFDUixHQUFHLEVBQUUsR0FBRztJQUNSLEdBQUcsRUFBRSxFQUFFO0NBQ1IsQ0FBQztBQUVGLFNBQVMsbUJBQW1CLENBQUMsQ0FBUyxFQUFFLENBQVM7SUFDL0MsSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUMxQixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ3RDLENBQUM7QUFFRCxxREFBcUQ7QUFFckQsTUFBTSxPQUFPLE9BQU87SUFDVCxLQUFLLENBQVc7SUFDaEIsS0FBSyxHQUFHLFFBQVEsQ0FBQztJQUNqQixPQUFPLEdBQUcsYUFBYSxDQUFDO0lBRWpDLFlBQVksSUFBYztRQUN4QixNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSw4Q0FBOEMsQ0FBQyxDQUFDO1FBQy9GLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFD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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eggjs/cookies",
3
- "version": "4.0.0-beta.20",
3
+ "version": "4.0.0-beta.21",
4
4
  "engines": {
5
5
  "node": ">=22.18.0"
6
6
  },
@@ -20,7 +20,7 @@
20
20
  "oxlint": "^1.19.0",
21
21
  "typescript": "^5.9.3",
22
22
  "tsdown": "^0.15.4",
23
- "@eggjs/tsconfig": "3.1.0-beta.20"
23
+ "@eggjs/tsconfig": "3.1.0-beta.21"
24
24
  },
25
25
  "repository": {
26
26
  "type": "git",
@@ -42,7 +42,7 @@
42
42
  "./package.json": "./package.json"
43
43
  },
44
44
  "scripts": {
45
- "build": "tsdown",
45
+ "build": "tsdown && rimraf dist && tsc -b --clean && tsc",
46
46
  "typecheck": "tsc --noEmit",
47
47
  "lint": "oxlint --type-aware",
48
48
  "lint:fix": "npm run lint -- --fix",