All files / src/lib/db session-store.ts

77.42% Statements 24/31
85.71% Branches 6/7
75% Functions 9/12
77.42% Lines 24/31

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116      69x   69x   69x                 69x               88x 88x 88x       3x       3x       4x       4x 2x   2x           1x     1x     1x       7x           1x       9x             9x 9x           4x                                       17x                 69x  
import EventEmitter from 'events';
import { Knex } from 'knex';
import { Logger, LogProvider } from '../logger';
import NotFoundError from '../error/notfound-error';
import { ISession, ISessionStore } from '../types/stores/session-store';
import { addDays } from 'date-fns';
 
const TABLE = 'unleash_session';
 
interface ISessionRow {
    sid: string;
    sess: string;
    created_at: Date;
    expired?: Date;
}
 
export default class SessionStore implements ISessionStore {
    private logger: Logger;
 
    private eventBus: EventEmitter;
 
    private db: Knex;
 
    constructor(db: Knex, eventBus: EventEmitter, getLogger: LogProvider) {
        this.db = db;
        this.eventBus = eventBus;
        this.logger = getLogger('lib/db/session-store.ts');
    }
 
    async getActiveSessions(): Promise<ISession[]> {
        const rows = await this.db<ISessionRow>(TABLE)
            .whereNull('expired')
            .orWhere('expired', '>', new Date())
            .orderBy('created_at', 'desc');
        return rows.map(this.rowToSession);
    }
 
    async getSessionsForUser(userId: number): Promise<ISession[]> {
        const rows = await this.db<ISessionRow>(TABLE).whereRaw(
            "(sess -> 'user' ->> 'id')::int = ?",
            [userId],
        );
        if (rows && rows.length > 0) {
            return rows.map(this.rowToSession);
        }
        throw new NotFoundError(
            `Could not find sessions for user with id ${userId}`,
        );
    }
 
    async get(sid: string): Promise<ISession> {
        const row = await this.db<ISessionRow>(TABLE)
            .where('sid', '=', sid)
            .first();
        Iif (row) {
            return this.rowToSession(row);
        }
        throw new NotFoundError(`Could not find session with sid ${sid}`);
    }
 
    async deleteSessionsForUser(userId: number): Promise<void> {
        await this.db<ISessionRow>(TABLE)
            .whereRaw("(sess -> 'user' ->> 'id')::int = ?", [userId])
            .del();
    }
 
    async delete(sid: string): Promise<void> {
        await this.db<ISessionRow>(TABLE).where('sid', '=', sid).del();
    }
 
    async insertSession(data: Omit<ISession, 'createdAt'>): Promise<ISession> {
        const row = await this.db<ISessionRow>(TABLE)
            .insert({
                sid: data.sid,
                sess: JSON.stringify(data.sess),
                expired: data.expired || addDays(Date.now(), 1),
            })
            .returning<ISessionRow>(['sid', 'sess', 'created_at', 'expired']);
        if (row) {
            return this.rowToSession(row);
        }
        throw new Error('Could not insert session');
    }
 
    async deleteAll(): Promise<void> {
        await this.db(TABLE).del();
    }
 
    destroy(): void {}
 
    async exists(sid: string): Promise<boolean> {
        const result = await this.db.raw(
            `SELECT EXISTS (SELECT 1 FROM ${TABLE} WHERE sid = ?) AS present`,
            [sid],
        );
        const { present } = result.rows[0];
        return present;
    }
 
    async getAll(): Promise<ISession[]> {
        const rows = await this.db<ISessionRow>(TABLE);
        return rows.map(this.rowToSession);
    }
 
    private rowToSession(row: ISessionRow): ISession {
        return {
            sid: row.sid,
            sess: row.sess,
            createdAt: row.created_at,
            expired: row.expired,
        };
    }
}
 
module.exports = SessionStore;