@kavach/cookie 1.0.0-next.25 → 1.0.0-next.27
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/.turbo/turbo-coverage.log +21 -18
- package/.turbo/turbo-format.log +8 -8
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-prepublishOnly.log +4 -4
- package/.turbo/turbo-test$colon$ci.log +9 -8
- package/coverage/index.html +7 -7
- package/coverage/index.js.html +186 -189
- package/coverage/lcov-report/index.html +7 -7
- package/coverage/lcov-report/index.js.html +186 -189
- package/coverage/lcov.info +84 -215
- package/dist/index.d.ts +0 -5
- package/package.json +9 -9
- package/spec/index.spec.js +9 -0
- package/spec/parse.spec.js +14 -14
- package/spec/serialize.spec.js +53 -64
- package/src/index.js +36 -37
- package/CHANGELOG.md +0 -16
package/spec/serialize.spec.js
CHANGED
|
@@ -1,168 +1,157 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import
|
|
2
|
+
import { parse, serialize } from '../src/index.js'
|
|
3
3
|
|
|
4
4
|
describe('Cookie Serialize', () => {
|
|
5
|
+
const identity = (v) => v
|
|
6
|
+
|
|
5
7
|
it('basic', () => {
|
|
6
|
-
expect(
|
|
7
|
-
expect(
|
|
8
|
-
expect(
|
|
9
|
-
expect(
|
|
8
|
+
expect(serialize('foo', 'bar')).toEqual('foo=bar')
|
|
9
|
+
expect(serialize('foo', 'bar baz')).toEqual('foo=bar%20baz')
|
|
10
|
+
expect(serialize('foo', '')).toEqual('foo=')
|
|
11
|
+
expect(() => serialize('foo\n', 'bar')).toThrowError(
|
|
10
12
|
/argument name is invalid/
|
|
11
13
|
)
|
|
12
|
-
expect(
|
|
14
|
+
expect(() => serialize('foo\n', 'bar')).toThrowError(
|
|
13
15
|
/argument name is invalid/
|
|
14
16
|
)
|
|
15
|
-
expect(
|
|
16
|
-
|
|
17
|
-
)
|
|
17
|
+
expect(() => serialize('foo\u280a', 'bar')).toThrowError(
|
|
18
|
+
/argument name is invalid/
|
|
19
|
+
)
|
|
20
|
+
expect(() => serialize('foo', 'bar', { encode: 42 })).toThrowError(
|
|
21
|
+
/option encode is invalid/
|
|
22
|
+
)
|
|
18
23
|
})
|
|
19
24
|
|
|
20
25
|
it('path', () => {
|
|
21
|
-
expect(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
expect(
|
|
25
|
-
cookie.serialize.bind(cookie, 'foo', 'bar', {
|
|
26
|
+
expect(serialize('foo', 'bar', { path: '/' })).toEqual('foo=bar; Path=/')
|
|
27
|
+
expect(() =>
|
|
28
|
+
serialize('foo', 'bar', {
|
|
26
29
|
path: '/\n'
|
|
27
30
|
})
|
|
28
31
|
).toThrowError(/option path is invalid/)
|
|
29
32
|
})
|
|
30
33
|
|
|
31
34
|
it('secure', () => {
|
|
32
|
-
expect(
|
|
33
|
-
|
|
34
|
-
)
|
|
35
|
-
expect(cookie.serialize('foo', 'bar', { secure: false })).toEqual('foo=bar')
|
|
35
|
+
expect(serialize('foo', 'bar', { secure: true })).toEqual('foo=bar; Secure')
|
|
36
|
+
expect(serialize('foo', 'bar', { secure: false })).toEqual('foo=bar')
|
|
36
37
|
})
|
|
37
38
|
|
|
38
39
|
it('domain', () => {
|
|
39
|
-
expect(
|
|
40
|
+
expect(serialize('foo', 'bar', { domain: 'example.com' })).toEqual(
|
|
40
41
|
'foo=bar; Domain=example.com'
|
|
41
42
|
)
|
|
42
|
-
expect(
|
|
43
|
-
|
|
43
|
+
expect(() =>
|
|
44
|
+
serialize('foo', 'bar', {
|
|
44
45
|
domain: 'example.com\n'
|
|
45
46
|
})
|
|
46
47
|
).toThrowError(/option domain is invalid/)
|
|
47
48
|
})
|
|
48
49
|
|
|
49
50
|
it('httpOnly', () => {
|
|
50
|
-
expect(
|
|
51
|
+
expect(serialize('foo', 'bar', { httpOnly: true })).toEqual(
|
|
51
52
|
'foo=bar; HttpOnly'
|
|
52
53
|
)
|
|
53
54
|
})
|
|
54
55
|
|
|
55
56
|
it('maxAge', () => {
|
|
56
57
|
expect(() =>
|
|
57
|
-
|
|
58
|
+
serialize('foo', 'bar', {
|
|
58
59
|
maxAge: 'buzz'
|
|
59
60
|
})
|
|
60
61
|
).toThrowError(/option maxAge is invalid/)
|
|
61
62
|
|
|
62
63
|
expect(() =>
|
|
63
|
-
|
|
64
|
+
serialize('foo', 'bar', {
|
|
64
65
|
maxAge: Infinity
|
|
65
66
|
})
|
|
66
67
|
).toThrowError(/option maxAge is invalid/)
|
|
67
68
|
|
|
68
|
-
expect(
|
|
69
|
+
expect(serialize('foo', 'bar', { maxAge: 1000 })).toEqual(
|
|
69
70
|
'foo=bar; Max-Age=1000'
|
|
70
71
|
)
|
|
71
|
-
expect(
|
|
72
|
+
expect(serialize('foo', 'bar', { maxAge: '1000' })).toEqual(
|
|
72
73
|
'foo=bar; Max-Age=1000'
|
|
73
74
|
)
|
|
74
|
-
expect(
|
|
75
|
+
expect(serialize('foo', 'bar', { maxAge: 0 })).toEqual('foo=bar; Max-Age=0')
|
|
76
|
+
expect(serialize('foo', 'bar', { maxAge: '0' })).toEqual(
|
|
75
77
|
'foo=bar; Max-Age=0'
|
|
76
78
|
)
|
|
77
|
-
expect(
|
|
78
|
-
|
|
79
|
-
)
|
|
80
|
-
expect(cookie.serialize('foo', 'bar', { maxAge: null })).toEqual('foo=bar')
|
|
81
|
-
expect(cookie.serialize('foo', 'bar', { maxAge: undefined })).toEqual(
|
|
82
|
-
'foo=bar'
|
|
83
|
-
)
|
|
84
|
-
expect(cookie.serialize('foo', 'bar', { maxAge: 3.14 })).toEqual(
|
|
79
|
+
expect(serialize('foo', 'bar', { maxAge: null })).toEqual('foo=bar')
|
|
80
|
+
expect(serialize('foo', 'bar')).toEqual('foo=bar')
|
|
81
|
+
expect(serialize('foo', 'bar', { maxAge: 3.14 })).toEqual(
|
|
85
82
|
'foo=bar; Max-Age=3'
|
|
86
83
|
)
|
|
87
84
|
})
|
|
88
85
|
|
|
89
86
|
it('expires', () => {
|
|
90
87
|
expect(
|
|
91
|
-
|
|
88
|
+
serialize('foo', 'bar', {
|
|
92
89
|
expires: new Date(Date.UTC(2000, 11, 24, 10, 30, 59, 900))
|
|
93
90
|
})
|
|
94
91
|
).toEqual('foo=bar; Expires=Sun, 24 Dec 2000 10:30:59 GMT')
|
|
95
92
|
|
|
96
|
-
expect(
|
|
97
|
-
|
|
93
|
+
expect(() =>
|
|
94
|
+
serialize('foo', 'bar', {
|
|
98
95
|
expires: Date.now()
|
|
99
96
|
})
|
|
100
97
|
).toThrowError(/option expires is invalid/)
|
|
101
98
|
})
|
|
102
99
|
|
|
103
100
|
it('sameSite', () => {
|
|
104
|
-
expect(
|
|
101
|
+
expect(serialize('foo', 'bar', { sameSite: true })).toEqual(
|
|
105
102
|
'foo=bar; SameSite=Strict'
|
|
106
103
|
)
|
|
107
|
-
expect(
|
|
104
|
+
expect(serialize('foo', 'bar', { sameSite: 'Strict' })).toEqual(
|
|
108
105
|
'foo=bar; SameSite=Strict'
|
|
109
106
|
)
|
|
110
|
-
expect(
|
|
107
|
+
expect(serialize('foo', 'bar', { sameSite: 'strict' })).toEqual(
|
|
111
108
|
'foo=bar; SameSite=Strict'
|
|
112
109
|
)
|
|
113
|
-
expect(
|
|
110
|
+
expect(serialize('foo', 'bar', { sameSite: 'Lax' })).toEqual(
|
|
114
111
|
'foo=bar; SameSite=Lax'
|
|
115
112
|
)
|
|
116
|
-
expect(
|
|
113
|
+
expect(serialize('foo', 'bar', { sameSite: 'lax' })).toEqual(
|
|
117
114
|
'foo=bar; SameSite=Lax'
|
|
118
115
|
)
|
|
119
|
-
expect(
|
|
116
|
+
expect(serialize('foo', 'bar', { sameSite: 'None' })).toEqual(
|
|
120
117
|
'foo=bar; SameSite=None'
|
|
121
118
|
)
|
|
122
|
-
expect(
|
|
119
|
+
expect(serialize('foo', 'bar', { sameSite: 'none' })).toEqual(
|
|
123
120
|
'foo=bar; SameSite=None'
|
|
124
121
|
)
|
|
125
|
-
expect(
|
|
126
|
-
'foo=bar'
|
|
127
|
-
)
|
|
122
|
+
expect(serialize('foo', 'bar', { sameSite: false })).toEqual('foo=bar')
|
|
128
123
|
|
|
129
|
-
expect(
|
|
130
|
-
|
|
124
|
+
expect(() =>
|
|
125
|
+
serialize('foo', 'bar', {
|
|
131
126
|
sameSite: 'foo'
|
|
132
127
|
})
|
|
133
128
|
).toThrowError(/option sameSite is invalid/)
|
|
134
129
|
})
|
|
135
130
|
|
|
136
131
|
it('escaping', () => {
|
|
137
|
-
expect(
|
|
132
|
+
expect(serialize('cat', '+ ')).toEqual('cat=%2B%20')
|
|
138
133
|
})
|
|
139
134
|
|
|
140
135
|
it('parse->serialize', () => {
|
|
141
|
-
expect(
|
|
142
|
-
cookie.parse(cookie.serialize('cat', 'foo=123&name=baz five'))
|
|
143
|
-
).toEqual({
|
|
136
|
+
expect(parse(serialize('cat', 'foo=123&name=baz five'))).toEqual({
|
|
144
137
|
cat: 'foo=123&name=baz five'
|
|
145
138
|
})
|
|
146
139
|
|
|
147
|
-
expect(
|
|
140
|
+
expect(parse(serialize('cat', ' ";/'))).toEqual({
|
|
148
141
|
cat: ' ";/'
|
|
149
142
|
})
|
|
150
143
|
})
|
|
151
144
|
|
|
152
145
|
it('unencoded', () => {
|
|
153
146
|
expect(
|
|
154
|
-
|
|
155
|
-
encode:
|
|
156
|
-
return value
|
|
157
|
-
}
|
|
147
|
+
serialize('cat', '+ ', {
|
|
148
|
+
encode: identity
|
|
158
149
|
})
|
|
159
150
|
).toEqual('cat=+ ')
|
|
160
151
|
|
|
161
|
-
expect(
|
|
162
|
-
|
|
163
|
-
encode:
|
|
164
|
-
return value
|
|
165
|
-
}
|
|
152
|
+
expect(() =>
|
|
153
|
+
serialize('cat', '+ \n', {
|
|
154
|
+
encode: identity
|
|
166
155
|
})
|
|
167
156
|
).toThrowError(/argument val is invalid/)
|
|
168
157
|
})
|
package/src/index.js
CHANGED
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
* @private
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const decode = decodeURIComponent
|
|
18
|
+
const encode = encodeURIComponent
|
|
19
|
+
const pairSplitRegExp = /; */
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* RegExp to match field-content in RFC 7230 sec 3.2
|
|
@@ -27,7 +27,7 @@ var pairSplitRegExp = /; */
|
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
// eslint-disable-next-line no-control-regex
|
|
30
|
-
|
|
30
|
+
const fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/u
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Parse a cookie header.
|
|
@@ -40,36 +40,36 @@ var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/
|
|
|
40
40
|
* @return {object}
|
|
41
41
|
* @public
|
|
42
42
|
*/
|
|
43
|
-
|
|
43
|
+
// eslint-disable-next-line
|
|
44
44
|
export function parse(str, options) {
|
|
45
45
|
if (typeof str !== 'string') {
|
|
46
46
|
throw new TypeError('argument str must be a string')
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
const obj = {}
|
|
50
|
+
const opt = options || {}
|
|
51
|
+
const pairs = str.split(pairSplitRegExp)
|
|
52
|
+
const dec = opt.decode || decode
|
|
53
53
|
|
|
54
|
-
for (
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
55
|
+
const pair = pairs[i]
|
|
56
|
+
let eq_idx = pair.indexOf('=')
|
|
57
57
|
|
|
58
58
|
// skip things that don't look like key=value
|
|
59
59
|
if (eq_idx < 0) {
|
|
60
60
|
continue
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
const key = pair.slice(0, eq_idx).trim()
|
|
64
|
+
let val = pair.slice(++eq_idx, pair.length).trim()
|
|
65
65
|
|
|
66
66
|
// quoted values
|
|
67
|
-
if (val[0]
|
|
67
|
+
if (val[0] === '"') {
|
|
68
68
|
val = val.slice(1, -1)
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// only assign once
|
|
72
|
-
if (
|
|
72
|
+
if (obj[key] === undefined) {
|
|
73
73
|
obj[key] = tryDecode(val, dec)
|
|
74
74
|
}
|
|
75
75
|
}
|
|
@@ -92,10 +92,10 @@ export function parse(str, options) {
|
|
|
92
92
|
* @return {string}
|
|
93
93
|
* @public
|
|
94
94
|
*/
|
|
95
|
-
|
|
95
|
+
// eslint-disable-next-line
|
|
96
96
|
export function serialize(name, val, options) {
|
|
97
|
-
|
|
98
|
-
|
|
97
|
+
const opt = { maxAge: null, ...(options || {}) }
|
|
98
|
+
const enc = opt.encode || encode
|
|
99
99
|
|
|
100
100
|
if (typeof enc !== 'function') {
|
|
101
101
|
throw new TypeError('option encode is invalid')
|
|
@@ -105,22 +105,22 @@ export function serialize(name, val, options) {
|
|
|
105
105
|
throw new TypeError('argument name is invalid')
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
|
|
108
|
+
const value = enc(val)
|
|
109
109
|
|
|
110
110
|
if (value && !fieldContentRegExp.test(value)) {
|
|
111
111
|
throw new TypeError('argument val is invalid')
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
let str = `${name}=${value}`
|
|
115
115
|
|
|
116
|
-
if (opt.maxAge
|
|
117
|
-
|
|
116
|
+
if (opt.maxAge !== null) {
|
|
117
|
+
const maxAge = opt.maxAge - 0
|
|
118
118
|
|
|
119
119
|
if (isNaN(maxAge) || !isFinite(maxAge)) {
|
|
120
120
|
throw new TypeError('option maxAge is invalid')
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
str +=
|
|
123
|
+
str += `; Max-Age=${Math.floor(maxAge)}`
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
if (opt.domain) {
|
|
@@ -128,7 +128,7 @@ export function serialize(name, val, options) {
|
|
|
128
128
|
throw new TypeError('option domain is invalid')
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
str +=
|
|
131
|
+
str += `; Domain=${opt.domain}`
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
if (opt.path) {
|
|
@@ -136,7 +136,7 @@ export function serialize(name, val, options) {
|
|
|
136
136
|
throw new TypeError('option path is invalid')
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
str +=
|
|
139
|
+
str += `; Path=${opt.path}`
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
if (opt.expires) {
|
|
@@ -144,7 +144,7 @@ export function serialize(name, val, options) {
|
|
|
144
144
|
throw new TypeError('option expires is invalid')
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
str +=
|
|
147
|
+
str += `; Expires=${opt.expires.toUTCString()}`
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
if (opt.httpOnly) {
|
|
@@ -156,7 +156,7 @@ export function serialize(name, val, options) {
|
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
if (opt.sameSite) {
|
|
159
|
-
|
|
159
|
+
const sameSite =
|
|
160
160
|
typeof opt.sameSite === 'string'
|
|
161
161
|
? opt.sameSite.toLowerCase()
|
|
162
162
|
: opt.sameSite
|
|
@@ -186,19 +186,18 @@ export function serialize(name, val, options) {
|
|
|
186
186
|
* Try decoding a string using a decoding function.
|
|
187
187
|
*
|
|
188
188
|
* @param {string} str
|
|
189
|
-
* @param {function}
|
|
190
|
-
* @
|
|
189
|
+
* @param {function} decodeFn
|
|
190
|
+
* @returns {string}
|
|
191
191
|
*/
|
|
192
|
-
|
|
193
|
-
function tryDecode(str, decode) {
|
|
192
|
+
function tryDecode(str, decodeFn) {
|
|
194
193
|
try {
|
|
195
|
-
return
|
|
194
|
+
return decodeFn(str)
|
|
196
195
|
} catch (e) {
|
|
197
196
|
return str
|
|
198
197
|
}
|
|
199
198
|
}
|
|
200
199
|
|
|
201
|
-
export default {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
200
|
+
// export default {
|
|
201
|
+
// parse,
|
|
202
|
+
// serialize
|
|
203
|
+
// }
|
package/CHANGELOG.md
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# @kavach/cookie
|
|
2
|
-
|
|
3
|
-
## 1.0.0-next.6
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- Added store for auth status and used alerts to display status on demo page.
|
|
8
|
-
|
|
9
|
-
## 1.0.0-next.5
|
|
10
|
-
|
|
11
|
-
### Patch Changes
|
|
12
|
-
|
|
13
|
-
- chore: release 1.0.0-next.4
|
|
14
|
-
- Split core package into logger and deflector
|
|
15
|
-
- 1a35ad0: Resolved linter errors.
|
|
16
|
-
- Releasing the next version.
|