Skip to content

Commit

Permalink
feat: add auth
Browse files Browse the repository at this point in the history
  • Loading branch information
risv1 committed Apr 22, 2024
1 parent e029893 commit 8b69d61
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
DB_URL="YOUR_DB_URL"
DB_URL="YOUR_DB_URL"
JWT_SECRET="YOUR_JWT_SECRET"
13 changes: 13 additions & 0 deletions models/users.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import {z} from 'zod';

export const UserSchema = z.object({
id: z.string(),
name: z.string(),
email: z.string().email(),
password: z.string().min(8),
role: z.string(),
created_at: z.string().datetime(),
updated_at: z.string().datetime(),
});

export type User = z.infer<typeof UserSchema>;
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
"dependencies": {
"@types/bcrypt": "^5.0.2",
"@types/jsonwebtoken": "^9.0.6",
"@types/uuid": "^9.0.8",
"bcrypt": "^5.1.1",
"drizzle-kit": "^0.20.17",
"drizzle-orm": "^0.30.9",
"jsonwebtoken": "^9.0.2",
"nuxt": "^3.11.2",
"postgres": "^3.4.4",
"uuid": "^9.0.1",
"vue": "^3.4.21",
"vue-router": "^4.3.0",
"zod": "^3.23.0"
Expand Down
15 changes: 15 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

58 changes: 58 additions & 0 deletions server/api/login.post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@

import jwt from "jsonwebtoken";
import bcrypt from "bcrypt";
import { users } from "~/database/schema";
import { db } from "~/database/db";
import { eq } from "drizzle-orm";
import { User } from "~/models/users";
import { config } from "dotenv";

config();

export default defineEventHandler(async (event) => {
try {
const body = await readBody(event);
if (!body.email || !body.password
) {
return {
message: "Please provide all required fields.",
statusCode: 400,
};
}

const [user]: User[] = await db.select().from(users).where(eq(users.email, body.email))
if (!user) {
return {
message: "User not found.",
statusCode: 400,
};
}

const isValid = await bcrypt.compare(body.password, user.password);
if (!isValid) {
return {
message: "Invalid password.",
statusCode: 400,
};
}

const token = jwt.sign(user, process.env.JWT_SECRET!, { expiresIn: "1h" });
if(!token) {
return {
message: "Token not created.",
statusCode: 400,
};
}

setCookie(event, "token", token, { httpOnly: true });

return { message: "User logged in successfully.", user: user };

} catch (e: any) {
console.error("Error: ", e);
return {
message: "Error: " + e,
statusCode: 500,
};
}
})
21 changes: 21 additions & 0 deletions server/api/logout.post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import jwt from "jsonwebtoken"

export default defineEventHandler(async(event)=>{
try{
const token = getCookie(event, "token") as string
const user = jwt.verify(token, "secret")
if(user){
setCookie(event, "token", "", {expires: new Date(0)})
return{
statusCode: 200,
message: "Logged out"
}
}
} catch(e){
console.error(e)
return {
message: "Error: " + e,
statusCode: 500,
};
}
})
58 changes: 58 additions & 0 deletions server/api/register.post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { v4 as uuidv4 } from "uuid";
import bcrypt from "bcrypt";
import { users } from "~/database/schema";
import { db } from "~/database/db";
import { User } from "~/models/users";

async function hashPassword(password: string) {
return await bcrypt.hash(password, 10);
}

export default defineEventHandler(async (event) => {
try {
const body = await readBody(event);
if (!body.name || !body.email || !body.password) {
return {
message: "Please provide all required fields.",
statusCode: 400,
};
}

const id = uuidv4();
const created_at = new Date().toISOString();

const data: User = {
id: id,
name: body.name,
email: body.email,
password: await hashPassword(body.password),
role: "user",
created_at: created_at,
updated_at: created_at,
};

const [user]: User[] = await db.insert(users).values({
...body,
id: data.id,
name: data.name,
email: data.email,
password: data.password,
role: data.role,
created_at: data.created_at,
updated_at: data.created_at,
});

if (!user) {
console.log("User not created");
return { message: "User not created.", statusCode: 400 };
}

return { message: "User created successfully.", user: user };
} catch (e: any) {
console.error("Error: ", e);
return {
message: "Error: " + e,
statusCode: 500,
};
}
});

0 comments on commit 8b69d61

Please sign in to comment.