DEV Community

Sokhavuth TIN
Sokhavuth TIN

Posted on • Edited on

2 1

Blog Engine with Fresh: Authenticating User


GitHub: https://github.com/Sokhavuth/deno-fresh
Deno Deploy: https://khmerweb-fresh.deno.dev/login


// routes/login.jsx

/** @jsx h */
import { h } from "preact";
import VLogin from '../components/front/login.jsx';
import CLogin from "../controllers/front/login.js";


export const handler = {
  async GET(req, ctx){
      return await CLogin.getForm(req, ctx);
  },  

  async POST(req, ctx){
      return await CLogin.checkUser(req, ctx);
  },
}


export default function Template(props){
    return (
        <VLogin data={props.data} />
    )
}
Enter fullscreen mode Exit fullscreen mode
// controllers/front/login.js

import { setCookie, getCookies, deleteCookie } from "cookies";
import { setting, secret_key, myredis } from 'setting';
import { create, verify, getNumericDate } from "jwt";
import userdb from "../../models/user.ts";
import { bcrypt } from "bcrypt";


class Login{
    async getForm(req, ctx){
        const cookies = getCookies(req.headers);

        if((cookies)&&(cookies.session_id)){
            const jwt = await myredis.get(cookies.session_id);
            try{
                const payload = await verify(jwt, secret_key, "HS512");
                if(payload.user){
                    return new Response(undefined, { headers: {location: `/admin/post`}, status: 302 });
                }
            }catch(error){
                console.log(error);
                const config = setting();
                config.page_title = "Login Page";
                const resp = new Response();
                deleteCookie(resp.headers, "session_id");
                return await ctx.render({"setting": config});
            }
        }   

        const config = setting();
        config.page_title = "Login Page";
        return await ctx.render({"setting": config});
    }

    async checkUser(req, ctx){
        const formData = await req.formData();

        const user = await userdb.checkUser(formData.get("email"));

        if(user){
            if(user.role in {'Admin':1,'Editor':1,'Author':1,"Guest":1}){
                if(await bcrypt.compareSync(formData.get("password"), user.password)){
                    const payload = { 
                        user: user, 
                        exp: getNumericDate(60 * 60 * 24), 
                    };
                    const jwt = await create({ alg: "HS512", typ: "JWT" }, payload, secret_key);
                    const resp = new Response(undefined, { headers: {location: `/admin/post`}, status: 302 });
                    const random_id = crypto.randomUUID();
                    await myredis.set(`${random_id}`, jwt, {ex: 60 * 60 * 24});
                    setCookie(resp.headers, { name: "session_id", value: `${random_id}` });
                    return resp;
                }else{
                    const config = setting();
                    config.page_title = "Login Page";
                    config.message = "The password is wrong!";
                    return await ctx.render({"setting": config});
                }
            }else{
                const config = setting();
                config.page_title = "Login Page";
                config.message = "You are not registered yet";
                return await ctx.render({"setting": config});
            }
        }else{
            const config = setting();
            config.page_title = "Login Page";
            config.message = "The email is wrong!";
            return await ctx.render({"setting": config});
        }    
    }
}

export default new Login();
Enter fullscreen mode Exit fullscreen mode
// models/user.ts

import { mydb } from "setting";
import { bcrypt } from "bcrypt";

interface UserSchema {
    _id: ObjectId;
    id: string; 
    title: string;
    content: string;
    thumb: string;
    date: string;
    role: string;
    email: string;
    password: string;
}

class User{
    async createRootUser(){
        const id = crypto.randomUUID();
        const salt = await bcrypt.genSalt(8);
        const hashPassword = bcrypt.hashSync('xxxxxxxxxxxxxxxxxx', salt);
        const newUser = {
            id: id, 
            title: 'Guest',
            content: '',
            thumb: '',
            date: '',
            role: 'Guest',
            email: 'guest@khmerweb.app',
            password: hashPassword,
        }

        const users = mydb.collection<UserSchema>("users");
        await users.insertOne(newUser);
    }

    async checkUser(email: string){
        const users = mydb.collection<UserSchema>("users");
        return await users.findOne({email: email});
    }
}

export default new User();
Enter fullscreen mode Exit fullscreen mode

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

Top comments (0)

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up