You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

70 lines
1.9 KiB

import { Injectable } from '../../../di/src/decorator/Injection.ts'
import { getCookies, setCookie, delCookie, ServerRequest } from '../external/http.ts'
import { InMemCache } from '../support/InMemCache.ts'
import { HTTPRequest } from './type/HTTPRequest.ts'
export interface Cookie {
key: string,
original_value: string,
value: any,
}
export type MaybeCookie = Cookie | undefined
// TODO cookie options (http only, expires, &c.)
@Injectable()
export class CookieJar {
protected _parsed: { [key: string]: string } = {}
protected _cache = new InMemCache()
constructor(
protected request: HTTPRequest,
) {
this._parsed = getCookies(this.request.to_native)
}
public async get(key: string): Promise<MaybeCookie> {
// Try the cache
if ( await this._cache.has(key) )
return this._cache.fetch(key)
// If the cache missed, try to parse it and load in cache
if ( key in this._parsed ) {
let value = this._parsed[key]
try {
value = JSON.parse(atob(this._parsed[key]))
} catch(e) {}
const cookie = {
key,
value,
original_value: this._parsed[key],
}
await this._cache.put(key, cookie)
return cookie
}
}
public async set(key: string, value: any): Promise<void> {
const original_value = btoa(JSON.stringify(value))
const cookie = {
key,
value,
original_value,
}
await this._cache.put(key, value)
setCookie(this.request.response, { name: key, value: original_value })
}
public async has(key: string): Promise<boolean> {
return (await this._cache.has(key)) || key in this._parsed
}
public async delete(key: string): Promise<void> {
await this._cache.drop(key)
delCookie(this.request.response, key)
}
}