e74b81aadea4102909c563b08a08c49052377d5d
[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                 const session = await this.session.validate(accountId, token);
43                 const account = await this.FindOne({id: session.account_id});
44
45                 if(!account) {
46                         throw new NotFoundError('User not found', ERROR_CODE.USER_NOT_FOUND);
47                 }
48
49                 return account;
50         }
51
52         async create(username: string, password: string) {
53                 const user = await this.Insert({
54                         id: uuid(),
55                         username: username,
56                         password: await this.hash(password)
57                 });
58
59                 if(!user) {
60                         throw new DuplicateContentError('Username in user', ERROR_CODE.USER_ALREADY_EXISTS);
61                 }
62
63                 return user;
64         }
65
66         async hash(password: string): Promise<string> {
67                 return bcrypt.hash(password, 10);
68         };
69 }