(input: {
userId: string;
loginHash: Uint8Array;
})
| 174 | } |
| 175 | |
| 176 | export async function assertCorrectUserPassword(input: { |
| 177 | userId: string; |
| 178 | loginHash: Uint8Array; |
| 179 | }) { |
| 180 | const user = await UserModel.query() |
| 181 | .findById(input.userId) |
| 182 | .select('encrypted_rehashed_login_hash'); |
| 183 | |
| 184 | if (user?.encrypted_rehashed_login_hash == null) { |
| 185 | throw new TRPCError({ |
| 186 | message: 'User not found.', |
| 187 | code: 'NOT_FOUND', |
| 188 | }); |
| 189 | } |
| 190 | |
| 191 | const passwordHashValues = getPasswordHashValues( |
| 192 | decryptUserRehashedLoginHash(user.encrypted_rehashed_login_hash), |
| 193 | ); |
| 194 | |
| 195 | const passwordValues = derivePasswordValues({ |
| 196 | password: input.loginHash, |
| 197 | salt: passwordHashValues.saltBytes, |
| 198 | }); |
| 199 | |
| 200 | const passwordIsCorrect = sodium.memcmp( |
| 201 | passwordValues.hash, |
| 202 | passwordHashValues.hashBytes, |
| 203 | ); |
| 204 | |
| 205 | if (!passwordIsCorrect) { |
| 206 | throw new TRPCError({ |
| 207 | message: 'Password is incorrect.', |
| 208 | code: 'BAD_REQUEST', |
| 209 | }); |
| 210 | } |
| 211 | } |
| 212 | |
| 213 | export async function assertUserSubscribed(input: { userId: string }) { |
| 214 | if ((await dataAbstraction().hget('user', input.userId, 'plan')) !== 'pro') { |
nothing calls this directly
no test coverage detected