Files
bare-operating-system/packages/bare-os-coreutils/lib/summon-cookie.js
T
Raven Scott 15afc148d7
Release rolling / release (push) Successful in 9m30s
Updates
2026-08-13 00:13:03 -04:00

125 lines
3.6 KiB
JavaScript

/** RFC 6265-ish cookie jar (first-party default). */
function bareSummonCookieHostMatch(domain, host) {
var d = String(domain || '')
.replace(/^\./, '')
.toLowerCase()
var h = String(host || '').toLowerCase()
if (!d || !h) return false
if (h === d) return true
return h.length > d.length && h.slice(h.length - d.length - 1) === '.' + d
}
function bareSummonCookiePathMatch(path, reqPath) {
var p = path || '/'
var r = reqPath || '/'
if (r === p) return true
if (r.indexOf(p) === 0) {
if (p.charAt(p.length - 1) === '/') return true
return r.charAt(p.length) === '/'
}
return false
}
function bareSummonParseSetCookie(raw, pageUrl) {
var s = String(raw || '')
var parts = s.split(';')
var nv = parts[0] || ''
var eq = nv.indexOf('=')
if (eq < 0) return null
var name = nv.slice(0, eq).trim()
var value = nv.slice(eq + 1).trim()
if (!name) return null
var rec = {
name: name,
value: value,
domain: '',
path: '/',
secure: false,
httpOnly: false,
expires: 0
}
for (var i = 1; i < parts.length; i++) {
var bit = parts[i].trim()
var e2 = bit.indexOf('=')
var k = (e2 < 0 ? bit : bit.slice(0, e2)).trim().toLowerCase()
var v = e2 < 0 ? '' : bit.slice(e2 + 1).trim()
if (k === 'domain') rec.domain = v.replace(/^\./, '').toLowerCase()
else if (k === 'path') rec.path = v || '/'
else if (k === 'secure') rec.secure = true
else if (k === 'httponly') rec.httpOnly = true
else if (k === 'max-age') {
var n = parseInt(v, 10)
if (Number.isFinite(n)) rec.expires = Date.now() + n * 1000
}
}
var u = bareSummonParseUrl(pageUrl)
if (!rec.domain && u) rec.domain = u.hostname
if ((!rec.path || rec.path === '/') && u && u.pathname) {
var slash = u.pathname.lastIndexOf('/')
rec.path = slash > 0 ? u.pathname.slice(0, slash) : '/'
}
if (u && rec.secure && u.protocol !== 'https:') return null
return rec
}
function bareSummonCreateCookieJar() {
var list = []
return {
list: list,
put: function (setCookieLine, pageUrl, opts) {
var rec = bareSummonParseSetCookie(setCookieLine, pageUrl)
if (!rec) return false
var u = bareSummonParseUrl(pageUrl)
if (
u &&
rec.domain &&
!bareSummonCookieHostMatch(rec.domain, u.hostname)
) {
return false
}
var third = opts && opts.thirdParty
if (!third && u && rec.domain && rec.domain !== u.hostname) {
/* first-party only: allow subdomain of page host */
if (!bareSummonCookieHostMatch(rec.domain, u.hostname)) return false
}
for (var i = list.length - 1; i >= 0; i--) {
if (
list[i].name === rec.name &&
list[i].domain === rec.domain &&
list[i].path === rec.path
) {
list.splice(i, 1)
}
}
list.push(rec)
return true
},
headerFor: function (pageUrl) {
var u = bareSummonParseUrl(pageUrl)
if (!u) return ''
var now = Date.now()
var bits = []
for (var i = 0; i < list.length; i++) {
var c = list[i]
if (c.expires && c.expires < now) continue
if (!bareSummonCookieHostMatch(c.domain, u.hostname)) continue
if (!bareSummonCookiePathMatch(c.path, u.pathname)) continue
if (c.secure && u.protocol !== 'https:') continue
bits.push(c.name + '=' + c.value)
}
return bits.join('; ')
},
toJSON: function () {
return list.slice()
},
load: function (arr) {
list.length = 0
if (!Array.isArray(arr)) return
for (var i = 0; i < arr.length; i++) {
if (arr[i] && arr[i].name) list.push(arr[i])
}
}
}
}