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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | 20x 20x 20x 6x 6x 6x 1x 5x 5x 5x 1x 4x 4x 4x 4x 1x 3x 3x 3x 6x 3x 3x 20x 3x 3x 3x 3x 20x 4x 4x 4x 4x 20x 3x 3x 6x 20x 3x 3x 1x 2x 2x 1x 2x 2x 1x 20x | /** * Services for the password reset table. * @packageDocumentation */ import { BaseService, getTime, newUniqueID, prunePasswordResetRecord, passwordResetIDLength, } from "./util"; /** * Password reset architecture. */ export interface PasswordReset { id: string; email: string; createTime: number; } /** * Password reset with only ID architecture. */ interface PasswordResetID { id: string; } /** * Password reset services. */ export class PasswordResetService extends BaseService { /** * Request a password reset. * * @param email The email address associated with the user's account. * @param prune Whether or not to prune the record when the time comes. * @returns The new password reset record's ID. */ public async requestPasswordReset( email: string, Iprune: boolean = true ): Promise<string> { // Confirm that the email address exists const emailUnused = await this.dbm.userService.uniqueEmail(email); if (emailUnused) { return null; } // Confirm account is verified const user = await this.dbm.userService.getUserByEmail(email); const verified = await this.dbm.userService.isVerified(user.id); if (!verified) { return null; } // Check that no password reset has already been requested let sql = `SELECT id FROM PasswordReset WHERE email = ?;`; let params: any[] = [email]; let rows: PasswordResetID[] = await this.dbm.execute(sql, params); if (rows.length > 0) { return null; } // Create the password reset record const newPasswordResetID = await newUniqueID( this.dbm, "PasswordReset", passwordResetIDLength ); sql = ` INSERT INTO PasswordReset ( id, email, createTime ) VALUES ( ?, ?, ? ); `; params = [newPasswordResetID, email, getTime()]; await this.dbm.execute(sql, params); Iif (prune) { prunePasswordResetRecord(this.dbm, newPasswordResetID); } return newPasswordResetID; } /** * Check if a password reset record exists. * * @param resetID A password reset record's ID. * @returns Whether or not the password reset record exists. */ public async resetRecordExists(resetID: string): Promise<boolean> { const sql = `SELECT id FROM PasswordReset WHERE id = ?;`; const params = [resetID]; const rows: PasswordResetID[] = await this.dbm.execute(sql, params); return rows.length > 0; } /** * Get a password reset record. * * @param resetID A password reset record's ID. * @returns The password reset record. */ public async getResetRecord(resetID: string): Promise<PasswordReset> { const sql = `SELECT * FROM PasswordReset WHERE id = ?;`; const params = [resetID]; const rows: PasswordReset[] = await this.dbm.execute(sql, params); return rows[0]; } /** * Delete a password reset record. * * @param resetID A password reset record's ID. */ public async deleteResetRecord(resetID: string): Promise<void> { const sql = `DELETE FROM PasswordReset WHERE id = ?;`; const params = [resetID]; await this.dbm.execute(sql, params); } /** * Reset a user's password. * * @param resetID A password reset record's ID. * @param newPassword The user's new password. * @returns Whether or not the reset was successful. */ public async resetPassword( resetID: string, newPassword: string ): Promise<boolean> { const resetRecord = await this.getResetRecord(resetID); if (!resetRecord) { return false; } const user = await this.dbm.userService.getUserByEmail(resetRecord.email); if (!user) { return false; } await this.dbm.userService.setUserPassword(user.id, newPassword); await this.deleteResetRecord(resetID); return true; } } |