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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | 69x 69x 69x 69x 69x 69x 87x 87x 87x 19x 19x 3x 16x 3x 3x 32x 32x 4x 4x 4x 1x 32x | import { EventEmitter } from 'events'; import { Knex } from 'knex'; import metricsHelper from '../util/metrics-helper'; import { DB_TIME } from '../metric-events'; import { Logger, LogProvider } from '../logger'; import NotFoundError from '../error/notfound-error'; import { IResetQuery, IResetToken, IResetTokenCreate, IResetTokenQuery, IResetTokenStore, } from '../types/stores/reset-token-store'; const TABLE = 'reset_tokens'; interface IResetTokenTable { reset_token: string; user_id: number; expires_at: Date; created_at: Date; created_by: string; used_at: Date; } const rowToResetToken = (row: IResetTokenTable): IResetToken => ({ userId: row.user_id, token: row.reset_token, expiresAt: row.expires_at, createdAt: row.created_at, createdBy: row.created_by, usedAt: row.used_at, }); export class ResetTokenStore implements IResetTokenStore { private logger: Logger; private timer: Function; private db: Knex; constructor(db: Knex, eventBus: EventEmitter, getLogger: LogProvider) { this.db = db; this.logger = getLogger('db/reset-token-store.ts'); this.timer = (action: string) => metricsHelper.wrapTimer(eventBus, DB_TIME, { store: 'reset-tokens', action, }); } async getActive(token: string): Promise<IResetToken> { const row = await this.db<IResetTokenTable>(TABLE) .where({ reset_token: token }) .where('expires_at', '>', new Date()) .first(); if (!row) { throw new NotFoundError('Could not find an active token'); } return rowToResetToken(row); } async getActiveTokens(): Promise<IResetToken[]> { const rows = await this.db<IResetTokenTable>(TABLE) .whereNull('used_at') .andWhere('expires_at', '>', new Date()); return rows.map(rowToResetToken); } async insert(newToken: IResetTokenCreate): Promise<IResetToken> { const [row] = await this.db<IResetTokenTable>(TABLE) .insert(newToken) .returning(['created_at']); return { userId: newToken.user_id, token: newToken.reset_token, expiresAt: newToken.expires_at, createdAt: row.created_at, createdBy: newToken.created_by, }; } async useToken(token: IResetQuery): Promise<boolean> { try { await this.db<IResetTokenTable>(TABLE) .update({ used_at: new Date() }) .where({ reset_token: token.token, user_id: token.userId }); return true; } catch (e) { return false; } } async deleteFromQuery({ reset_token }: IResetTokenQuery): Promise<void> { return this.db(TABLE).where(reset_token).del(); } async deleteAll(): Promise<void> { return this.db(TABLE).del(); } async deleteExpired(): Promise<void> { return this.db(TABLE).where('expires_at', '<', new Date()).del(); } async expireExistingTokensForUser(user_id: number): Promise<void> { await this.db<IResetTokenTable>(TABLE).where({ user_id }).update({ expires_at: new Date(), }); } async delete(reset_token: string): Promise<void> { await this.db(TABLE).where({ reset_token }).del(); } destroy(): void {} async exists(reset_token: string): Promise<boolean> { const result = await this.db.raw( `SELECT EXISTS (SELECT 1 FROM ${TABLE} WHERE reset_token = ?) AS present`, [reset_token], ); const { present } = result.rows[0]; return present; } async get(key: string): Promise<IResetToken> { const row = await this.db(TABLE).where({ reset_token: key }).first(); return rowToResetToken(row); } async getAll(): Promise<IResetToken[]> { const rows = await this.db(TABLE).select(); return rows.map(rowToResetToken); } } |