chore(release): 0.2.17
[risinglegends.git] / src / server / auth.ts
1 import { Player } from 'shared/player';
2 import xss from 'xss';
3 import bcrypt from 'bcrypt';
4 import { loadPlayer } from './player';
5 import { Auth } from '../shared/auth';
6 import { db } from './lib/db';
7 import { Request, Response } from 'express';
8
9 export interface AuthRequest extends Request {
10   player: Player
11 }
12
13 export async function signup(playerId: string, username: string, password: string): Promise<void> {
14   const salt = await bcrypt.genSalt(10);
15   const hash = await bcrypt.hash(password, salt);
16   const data: Auth = {
17     id: playerId,
18     username: xss(username, { whiteList: {} }),
19     password: hash
20   };
21
22   try {
23     const res: any = await db.insert(data).into('auth');
24     if(res.rowCount === 1) {
25       return;
26     }
27     else {
28       console.log(res);
29       throw new Error('Something weird happened..');
30     }
31
32   }
33   catch(e) {
34     console.log(e);
35     if(e?.code === '23505') {
36       if(e?.constraint === 'auth_pkey') {
37         console.log(`Key ${playerId} was already claimed. ${data.username} tried claiming again..`);
38       }
39       // someone already claimed this key
40       throw new Error('Invalid account');
41     }
42   }
43
44 }
45
46 export async function login(username: string, password: string): Promise<Player> {
47   const auth = await db.select('*').first().from<Auth>('auth').where({
48     username
49   });
50
51   if(auth) {
52     const compare = await bcrypt.compare(password, auth.password);
53     if(compare) {
54       return loadPlayer(auth.id);
55     }
56     else {
57       throw new Error(`Invalid password for ${username}`);
58     }
59   }
60   else {
61     throw new Error(`Requested user ${username}, does not exist`);
62   }
63
64 }
65
66 export async function authEndpoint(req: AuthRequest, res: Response, next: any) {
67   const authToken = req.headers['x-authtoken'];
68   if(!authToken) {
69     console.log(`Invalid auth token ${authToken}`);
70     res.sendStatus(401)
71   }
72   else {
73     const player: Player = await loadPlayer(authToken.toString());
74     if(player) {
75       req.player = player;
76       next()
77     }
78     else {
79       console.log(`Invalid auth token ${authToken}`);
80       res.sendStatus(401);
81     }
82   }
83 }