// routes/login.tsx

/** @jsx h */
import { h } from "preact";
import { setting, secret_key, redis_db } from 'setting';
import { Handlers, PageProps } from "$fresh/server.ts";
import Login from '../components/front/login.tsx';
import userdb from "../models/user.ts";
import { create, verify, getNumericDate } from "jwt";
import { bcrypt } from "bcrypt";
import { setCookie, getCookies, deleteCookie } from "cookies";


export const handler: Handlers = {
  async GET(req, ctx) {
    const cookies = getCookies(req.headers);
    if((cookies)&&(cookies.session_id)){
      const jwt = await redis_db.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){
        const config = setting();
        config.page_title = "ទំព័រ​ចុះ​ឈ្មោះ";
        const resp = new Response();
        deleteCookie(resp.headers, "session_id");
        return await ctx.render({"setting": config});
      }
    }

    const config = setting();
    config.page_title = "ទំព័រ​ចុះ​ឈ្មោះ";
    return await ctx.render({"setting": config});
  },


  async POST(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 redis_db.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 = "ទំព័រ​ចុះ​ឈ្មោះ";
          config.message = "ពាក្យ​សំងាត់​មិន​ត្រឹមត្រូវ​ទេ!";
          return await ctx.render({"setting": config});
        }
      }else{
        const config = setting();
        config.page_title = "ទំព័រ​ចុះ​ឈ្មោះ";
        config.message = "អ្នក​មិន​ទាន់មាន​ឈ្មោះ​ក្នុង​បញ្ជី​ទេ";
        return await ctx.render({"setting": config});
      }
    }else{
      const config = setting();
      config.page_title = "ទំព័រ​ចុះ​ឈ្មោះ";
      config.message = "Email ​មិន​ត្រឹមត្រូវ​ទេ!";
      return await ctx.render({"setting": config});
    }    
  }
}


export default function Template(props: PageProps){
  return (
      <Login data={props.data} />
  )
}

 

// models/user.ts

import { mongo_db } 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 = mongo_db.collection<UserSchema>("users");
        await users.insertOne(newUser);
    }

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

export default new User();

 

GitHub: https://github.com/Sokhavuth/khmerweb-fresh

Deno Deploy: https://khmerweb.deno.dev/login