diff --git a/apiDocs/lstV2/Auth/Login.bru b/apiDocs/lstV2/Auth/Login.bru
index 71070ea..b0eec0e 100644
--- a/apiDocs/lstV2/Auth/Login.bru
+++ b/apiDocs/lstV2/Auth/Login.bru
@@ -12,7 +12,7 @@ post {
body:json {
{
- "username": "admin",
- "password": "password123"
+ "username": "adm_matthes",
+ "password": "nova0511"
}
}
diff --git a/apiDocs/lstV2/Auth/Register.bru b/apiDocs/lstV2/Auth/Register.bru
index 5eb4361..3f7be91 100644
--- a/apiDocs/lstV2/Auth/Register.bru
+++ b/apiDocs/lstV2/Auth/Register.bru
@@ -12,9 +12,8 @@ post {
body:json {
{
- "username":"matthes02",
- "email": "blake@alpla.com",
- "password": "Vsd!134"
-
+ "username": "adm_matthes",
+ "email":"blake@alpla.com",
+ "password": "nNova0511!"
}
}
diff --git a/frontend/src/components/extendedUI/LstCard.tsx b/frontend/src/components/extendedUI/LstCard.tsx
index 1f3ed83..167b7dd 100644
--- a/frontend/src/components/extendedUI/LstCard.tsx
+++ b/frontend/src/components/extendedUI/LstCard.tsx
@@ -10,7 +10,7 @@ interface LstCardProps {
export function LstCard({children, className = "", style = {}}: LstCardProps) {
return (
-
+
{children}
diff --git a/globals.d.ts b/globals.d.ts
new file mode 100644
index 0000000..603cf74
--- /dev/null
+++ b/globals.d.ts
@@ -0,0 +1,10 @@
+declare global {
+ namespace NodeJS {
+ interface ProcessEnv {
+ JWT_SECRET: string;
+ JWT_EXPIRES: string;
+ }
+ }
+}
+
+export {};
diff --git a/package.json b/package.json
index 184db1f..28695a9 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
"@hono/zod-openapi": "^0.18.4",
"@scalar/hono-api-reference": "^0.5.175",
"@types/bun": "^1.2.2",
+ "@types/jsonwebtoken": "^9.0.8",
"axios": "^1.7.9",
"bcrypt": "^5.1.1",
"compression": "^1.8.0",
diff --git a/server/src/services/auth/controllers/login.ts b/server/src/services/auth/controllers/login.ts
index 0031f87..cd3484a 100644
--- a/server/src/services/auth/controllers/login.ts
+++ b/server/src/services/auth/controllers/login.ts
@@ -1,28 +1,39 @@
import {sign, verify} from "jsonwebtoken";
+import {db} from "../../../../database/dbClient";
+import {users} from "../../../../database/schema/users";
+import {eq} from "drizzle-orm";
+import {checkPassword} from "../utils/checkPassword";
/**
* Authenticate a user and return a JWT.
*/
-const fakeUsers = [
- {id: 1, username: "admin", password: "password123", role: "admin"},
- {id: 2, username: "user", password: "pass", role: "user"},
- {id: 3, username: "user2", password: "password123", role: "user"},
-];
-
-export function login(
+export async function login(
username: string,
password: string
-): {token: string; user: {id: number; username: string; role: string}} {
- const user = fakeUsers.find((u) => u.username === username && u.password === password);
- if (!user) {
- throw new Error("Invalid credentials");
+): Promise<{token: string; user: {user_id: string; username: string}}> {
+ const user = await db.select().from(users).where(eq(users.username, username));
+
+ if (user.length === 0) {
+ throw new Error("Invalid or Missing user");
+ }
+ // check the password
+ const checkedPass = await checkPassword(password, user[0]?.password);
+ console.log(checkedPass);
+ if (!checkedPass) {
+ throw new Error("Invalid Password");
}
// Create a JWT
- const token = sign({user}, process.env.JWT_SECRET, {
- expiresIn: process.env.JWT_EXPIRES,
- });
+ const secret: string = process.env.JWT_SECRET! || "bnghsjhsd";
+ const expiresIn: string = process.env.JWT_EXPIRES! || "1h";
- return {token, user: {id: user?.id, username: user.username, role: user.role}};
+ const userData = {
+ user_id: user[0].user_id,
+ username: user[0].username,
+ email: user[0].email,
+ };
+ const token = sign({user: userData}, secret, {expiresIn: 60 * 60});
+
+ return {token, user: {user_id: user[0].user_id, username: user[0].username}};
}
diff --git a/server/src/services/auth/controllers/verifyToken.ts b/server/src/services/auth/controllers/verifyToken.ts
index 50a278d..1d1f548 100644
--- a/server/src/services/auth/controllers/verifyToken.ts
+++ b/server/src/services/auth/controllers/verifyToken.ts
@@ -3,9 +3,13 @@ import {sign, verify} from "jsonwebtoken";
/**
* Verify a JWT and return the decoded payload.
*/
+
+const secret: string = process.env.JWT_SECRET! || "bnghsjhsd";
+const expiresIn: string = process.env.JWT_EXPIRES! || "1h";
+
export function verifyToken(token: string): {userId: number} {
try {
- const payload = verify(token, process.env.JWT_SECRET) as {userId: number};
+ const payload = verify(token, secret) as {userId: number};
return payload;
} catch (err) {
throw new Error("Invalid token");
diff --git a/server/src/services/auth/routes/login.ts b/server/src/services/auth/routes/login.ts
index 0a42154..130378a 100644
--- a/server/src/services/auth/routes/login.ts
+++ b/server/src/services/auth/routes/login.ts
@@ -65,7 +65,7 @@ const route = createRoute({
app.openapi(route, async (c) => {
const {username, password, email} = await c.req.json();
- if (!username || !password || !email) {
+ if (!username || !password) {
return c.json(
{
success: false,
@@ -75,8 +75,9 @@ app.openapi(route, async (c) => {
);
}
+ const {token, user} = await login(username.toLowerCase(), password);
try {
- const {token, user} = login(username.toLowerCase(), password);
+ const {token, user} = await login(username.toLowerCase(), password);
// Set the JWT as an HTTP-only cookie
//c.header("Set-Cookie", `auth_token=${token}; HttpOnly; Secure; Path=/; SameSite=None; Max-Age=3600`);
@@ -87,29 +88,4 @@ app.openapi(route, async (c) => {
}
});
-/*
- let body = {username: "", password: "", error: ""};
- try {
- body = await c.req.json();
- } catch (error) {
- return c.json({success: false, message: "Username and password required"}, 400);
- }
-
- if (!body?.username || !body?.password) {
- return c.json({message: "Username and password required"}, 400);
- }
- try {
- const {token, user} = login(body?.username, body?.password);
-
- // Set the JWT as an HTTP-only cookie
- c.header("Set-Cookie", `auth_token=${token}; HttpOnly; Secure; Path=/; SameSite=None; Max-Age=3600`);
-
- return c.json({message: "Login successful", user});
- } catch (err) {
- // console.log(err);
- return c.json({message: err}, 401);
- }
-
-
-*/
export default app;
diff --git a/server/src/services/auth/routes/session.ts b/server/src/services/auth/routes/session.ts
index 02486ee..281a7a0 100644
--- a/server/src/services/auth/routes/session.ts
+++ b/server/src/services/auth/routes/session.ts
@@ -3,55 +3,97 @@ import {verify} from "hono/jwt";
const session = new OpenAPIHono();
const tags = ["Auth"];
-const JWT_SECRET = process.env.JWT_SECRET;
+const JWT_SECRET = process.env.JWT_SECRET!;
-const route = createRoute({
- tags: ["Auth"],
- summary: "Checks a user session based on there token",
- description: "Can post there via Authentiaction header or cookies",
- method: "get",
- path: "/",
- request: {body: {content: {"application/json": {schema: {username: "", password: ""}}}}},
- responses: {
- 200: {
- content: {
- "application/json": {
- schema: {session: ""},
- },
- },
- description: "Login successful",
- },
- 401: {
- content: {
- "application/json": {
- schema: {message: ""},
- },
- },
- description: "Error of why you were not logged in.",
- },
- },
+const UserSchema = z.object({
+ username: z
+ .string()
+ .regex(/^[a-zA-Z0-9_]{3,30}$/)
+ .openapi({example: "smith034"}),
+ email: z.string().email().openapi({example: "smith@example.com"}),
+ password: z
+ .string()
+ .min(6, {message: "Passwords must be longer than 3 characters"})
+ .regex(/[A-Z]/, {message: "Password must contain at least one uppercase letter"})
+ .regex(/[\W_]/, {message: "Password must contain at least one special character"})
+ .openapi({example: "Password1!"}),
});
-session.openapi(route, async (c) => {
- const authHeader = c.req.header("Authorization");
- if (authHeader?.includes("Basic")) {
- //
- return c.json({message: "You are a Basic user! Please login to get a token"}, 401);
+session.openapi(
+ createRoute({
+ tags,
+ summary: "Checks a user session based on there token",
+ description: "Can post there via Authentiaction header or cookies",
+ method: "get",
+ path: "/",
+ // request: {
+ // body: {
+ // content: {
+ // "application/json": {schema: UserSchema},
+ // },
+ // },
+ // },
+ responses: {
+ 200: {
+ content: {
+ "application/json": {
+ schema: z.object({
+ data: z.object({
+ token: z.string().openapi({example: "sdkjhgsldkvhdakl;jvhs;adkjfhvds.kvnsad;ovhads"}),
+ // user: z.object({
+ // user_id: z.string().openapi({example: "04316c86-f086-4cc6-b3d4-cca164a26f3f"}),
+ // username: z.string().openapi({example: "smith"}),
+ // email: z.string().openapi({example: "smith@example.com"}).optional(),
+ // }),
+ }),
+ }),
+ },
+ },
+ description: "Login successful",
+ },
+ 401: {
+ content: {
+ "application/json": {
+ schema: z.object({
+ message: z.string().openapi({example: "Unathenticated"}),
+ }),
+ },
+ },
+ description: "Error of why you were not logged in.",
+ },
+ },
+ }),
+ async (c) => {
+ const authHeader = c.req.header("Authorization");
+
+ if (authHeader?.includes("Basic")) {
+ return c.json({message: "You are a Basic user! Please login to get a token"}, 401);
+ }
+
+ if (!authHeader) {
+ return c.json({message: "Unauthorized"}, 401);
+ }
+
+ const token = authHeader?.split("Bearer ")[1] || "";
+
+ try {
+ const payload = await verify(token, process.env.JWT_SECRET!);
+ return c.json({data: {token: token, user: payload.user}}, 200);
+ } catch (error) {}
+ return c.json({data: {token: "tsfds"}}, 200);
}
+);
- if (!authHeader) {
- return c.json({error: "Unauthorized"}, 401);
- }
+// const token = authHeader?.split("Bearer ")[1] || "";
- const token = authHeader?.split("Bearer ")[1] || "";
-
- try {
- const payload = await verify(token, JWT_SECRET);
- //console.log(payload);
- return c.json({data: {token, user: payload.user}});
- } catch (err) {
- return c.json({error: "Invalid or expired token"}, 401);
- }
-});
+// try {
+// const payload = await verify(token, process.env.JWT_SECRET!);
+// //console.log(payload);
+// //return c.json({data: {token, user: payload.user}}, 200);
+// return c.json({message: "something"});
+// } catch (err) {
+// return c.json({error: "Invalid or expired token"}, 401);
+// }
+// });
export default session;
diff --git a/server/src/services/auth/utils/checkPassword.ts b/server/src/services/auth/utils/checkPassword.ts
new file mode 100644
index 0000000..75ccdb2
--- /dev/null
+++ b/server/src/services/auth/utils/checkPassword.ts
@@ -0,0 +1,10 @@
+import bcrypt from "bcrypt";
+
+export const checkPassword = async (currentPassword: string, dbPassword: string) => {
+ // encypt password
+ const pass: string | undefined = process.env.SECRET;
+
+ const checked = bcrypt.compareSync(pass + currentPassword, dbPassword);
+
+ return checked;
+};
diff --git a/server/src/services/auth/utils/createPassword.ts b/server/src/services/auth/utils/createPassword.ts
index 3f2fd75..f071ebd 100644
--- a/server/src/services/auth/utils/createPassword.ts
+++ b/server/src/services/auth/utils/createPassword.ts
@@ -8,9 +8,9 @@ export const createPassword = async (password: string) => {
if (!pass || !salt) {
pass = "error";
} else {
- pass = bcrypt.hashSync(process.env.SECRET + password, parseInt(salt));
+ pass = bcrypt.hashSync(pass + password, parseInt(salt));
- pass = btoa(pass);
+ // pass = btoa(pass);
}
return pass;