File size: 4,803 Bytes
c13f601
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
162
163
import { lucia } from "./auth.js";
import { generateId, Lucia } from "lucia";
import { loginSchema, signUpSchema } from "./schemas.js";
import bcrypt from "bcrypt";
import { Database } from "better-sqlite3";
import { Socket } from "socket.io";
import { getDB } from "./db.js";

var db: Database;
db = getDB();

// middleware
export const authCookieMiddleware = (async (req: any, res: any, next: any) => {
    const sessionId = lucia.readSessionCookie(req.headers.cookie ?? "");
    if (!sessionId) {
        res.locals.user = null;
        res.locals.session = null;
        return next();
    }
    const { session, user } = await lucia.validateSession(sessionId);
    if (session && session.fresh) {
        res.appendHeader("Set-Cookie", lucia.createSessionCookie(session.id).serialize());
    }
    if (!session) {
        res.appendHeader("Set-Cookie", lucia.createBlankSessionCookie().serialize());
    }
    res.locals.session = session;
    res.locals.user = user;
    // console.log(res.locals.session);
    // console.log(res.locals.user);
    return next();

})

export const isAuthAPIMiddleware = async (req: any, res: any, next: any) => {
    const sessionId = lucia.readSessionCookie(req.headers.cookie ?? "");
    // console.log(sessionId);

    if (!sessionId) {

        return res.status(403).send({ error: "unauthorized" });
    }
    const { session, user } = await lucia.validateSession(sessionId);
    if (!session) {
        return res.status(403).send({ error: "unauthorized" });
    }
    return next();
};

export const isAuthSocketMiddleware = async (socket: Socket, next: any) => {
    const sessionId = lucia.readSessionCookie(socket.handshake.headers.cookie ?? "");
    console.log(sessionId);
    if (!sessionId) return next(new Error("error"));

    const { session, user } = await lucia.validateSession(sessionId);
    if (!session) {
        // return res.end();
        return next(new Error("error"));
    }

    // add user and session to the socket.data object
    socket.data.user = user;
    socket.data.session = session;

    return next();
};


export const signup_handler = async (req: any, res: any) => {

    // console.log(req.params);
    // console.log(req.body);
    const parsedData = signUpSchema.safeParse(req.body);
    if (!parsedData.success) {
        return res.status(403).json({ field_error: parsedData.error.flatten().fieldErrors }); // 403 is for validation error
    }

    var data = parsedData.data;
    // check if password and confirm_password matchs
    if (data.password != data.confirm_password) {
        return res.status(403).json({
            field_error: {
                confirm_password: [
                    "password doesn't match"
                ]
            }
        });
    }

    // check if username is already used
    var row = db.prepare("select * from users where id=?").get(data.username);
    if (row) {
        return res.status(403).json({
            field_error: {
                username: [
                    "username already used."
                ]
            }
        })
    }

    // save to data se
    const hashedPassword = await bcrypt.hash(data.password, 10);

    await db.prepare("insert into users(id,name,password) values(?,?,?)").run(
        data.username,
        data.name,
        hashedPassword
    );

    const session = await lucia.createSession(data.username, {});
    const sessionCookie = lucia.createSessionCookie(session.id);

    res.cookie(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);

    res.json({
        "status": "success",
        "msg": "user created successfully",
    });

};

export const login_handler = (async (req: any, res: any) => {
    // console.log(req.body);

    const parsedData = loginSchema.safeParse(req.body);

    if (!parsedData.success) {
        return res.status(403).json({
            "field_error": parsedData.error.flatten().fieldErrors
        })
    }

    // check if user exists 
    const row: any = db.prepare("select * from users where id=?").get(parsedData.data.username);
    // console.log(row);

    if (!row) {
        return res.status(403).json({
            "error": "Incorrect username or password"
        })
    }

    // check password
    if (!await bcrypt.compare(parsedData.data.password, row.password)) {
        return res.status(403).json({
            "error": "Incorrect username or password"
        })
    }

    // save session
    const session = await lucia.createSession(row.id, {});
    const sessionCookie = lucia.createSessionCookie(session.id);

    // console.log(sessionCookie.attributes);
    res.cookie(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);

    res.json({
        "status": "success",
        "msg": "logged in successfully",
    });

})