bugfix: don't crash on invalid session
[browser-rts.git] / src / repository / accounts.ts
1 import {DuplicateContentError, ERROR_CODE, NotFoundError} from '../errors';
2 import { v4 as uuid } from 'uuid';
3 import {Repository} from './base';
4 import { Session, SessionRepository } from './session';
5 import bcrypt from 'bcrypt';
6
7 export type Account = {
8         id: string;
9         username: string;
10         password: string;
11 }
12
13 export class AccountRepository extends Repository<Account> {
14         session: SessionRepository;
15         constructor() {
16                 super('accounts');
17                 this.session = new SessionRepository();
18         }
19
20         async login(username: string, password: string): Promise<{account: Account, session: Session}> {
21                 const account = await this.FindOne({
22                         username: username
23                 });
24
25                 if(!account) {
26                         throw new NotFoundError('User not found', ERROR_CODE.USER_NOT_FOUND);
27                 }
28
29                 if(!await bcrypt.compare(password, account.password)) {
30                         throw new NotFoundError('User not found', ERROR_CODE.USER_PASSWORD_INCORRECT);
31                 }
32
33                 const session = await this.session.create(account.id);
34
35                 return {
36                         account,
37                         session
38                 };
39         }
40
41         async validate(accountId: string, token: string): Promise<Account> {
42     try {
43       const session = await this.session.validate(accountId, token);
44       const account = await this.FindOne({id: session.account_id});
45
46       if(!account) {
47         throw new NotFoundError('User not found', ERROR_CODE.USER_NOT_FOUND);
48       }
49       return account;
50     }
51     catch(e) {
52       throw new NotFoundError('User not found', ERROR_CODE.INVALID_USER_TOKEN);
53     }
54         }
55
56         async create(username: string, password: string) {
57                 const user = await this.Insert({
58                         id: uuid(),
59                         username: username,
60                         password: await this.hash(password)
61                 });
62
63                 if(!user) {
64                         throw new DuplicateContentError('Username in user', ERROR_CODE.USER_ALREADY_EXISTS);
65                 }
66
67                 return user;
68         }
69
70         async hash(password: string): Promise<string> {
71                 return bcrypt.hash(password, 10);
72         };
73 }