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.
lib/src/http/session/CacheSession.ts

120 lines
2.7 KiB

import {NoSessionKeyError, Session, SessionData, SessionNotLoadedError} from './Session'
import {Inject, Injectable} from '../../di'
import {Cache, Maybe} from '../../util'
import {Config} from '../../service/Config'
/**
* A Session implementation that uses the configured Cache driver for persistence.
*/
@Injectable()
export class CacheSession extends Session {
@Inject()
protected readonly cache!: Cache
@Inject()
protected readonly config!: Config
protected key?: string
protected data?: SessionData
protected dirty = false
forget(key: string): void {
if ( !this.data ) {
throw new SessionNotLoadedError()
}
delete this.data[key]
this.dirty = true
}
get(key: string, fallback?: unknown): any {
if ( !this.data ) {
throw new SessionNotLoadedError()
}
return this.data[key] ?? fallback
}
getData(): SessionData {
if ( !this.data ) {
throw new SessionNotLoadedError()
}
return {...this.data}
}
getKey(): string {
if ( !this.key ) {
throw new NoSessionKeyError()
}
return this.key
}
async load(): Promise<void> {
const json = await this.cache.fetch(this.formatKey())
if ( json ) {
this.data = JSON.parse(json)
} else {
this.data = {}
}
this.dirty = false
}
async persist(): Promise<void> {
if ( !this.dirty ) {
return
}
const json = JSON.stringify(this.data)
await this.cache.put(this.formatKey(), json, this.getExpiration())
this.dirty = false
}
private getExpiration(): Maybe<Date> {
// Get the session expiration. By default, this is 4 hours.
const durationMins = this.config.safe('server.session.durationMins')
.or(4 * 60)
.integer()
if ( durationMins !== 0 ) {
const date = new Date()
date.setMinutes(date.getMinutes() + durationMins)
return date
}
}
private formatKey(): string {
if ( !this.key ) {
throw new NoSessionKeyError()
}
const prefix = this.config.safe('app.name')
.or('Extollo')
.string()
return `${prefix}_session_${this.key}`
}
set(key: string, value: unknown): void {
if ( !this.data ) {
throw new SessionNotLoadedError()
}
this.data[key] = value
this.dirty = true
}
setData(data: SessionData): void {
this.data = {...data}
this.dirty = true
}
setKey(key: string): void {
this.key = key
}
}