Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add auth #26

Merged
merged 15 commits into from
Nov 10, 2024
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
public-hoist-pattern[]=*
46 changes: 46 additions & 0 deletions apps/api/app/api/[[...route]]/hello.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Hono } from "hono";
const app = new Hono();
import { prisma } from "@repo/db";
Comment on lines +1 to +3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

Request validation is already supported but not implemented

The project already has @hono/zod-validator and zod dependencies installed, and there's an existing pattern of request validation in mail.ts using zValidator middleware. You should implement similar validation for your endpoints using the existing setup:

  • Import zValidator from @hono/zod-validator
  • Define request schemas in @repo/types
  • Apply zValidator middleware to your routes

Example from mail.ts:

import { zValidator } from "@hono/zod-validator";
app.post("/send", zValidator("json", mailSchema), async (c) => {
  const { email, subject } = c.req.valid("json");
  // ...
});
🔗 Analysis chain

Consider adding request validation middleware.

Since this is an authentication-related PR, it's crucial to validate incoming requests. Consider adding middleware like zod for request validation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if zod is already being used in the project
rg -l "from ['\"](zod|@repo/validator)['\"]"

Length of output: 57


Script:

#!/bin/bash
# Check for any validation or middleware usage in the project
rg -l "validator|middleware|validation|schema"

# Check package.json for validation-related dependencies
fd -t f "package.json" --exec cat {} \; | jq -r '.dependencies,.devDependencies | select(. != null) | keys[]' | grep -iE "validator|zod|middleware|schema"

# Look for any existing validation patterns in the codebase
ast-grep --pattern 'import $_ from "$_"
$$$
const $_ = $_.$_($$$)'

Length of output: 618


Script:

#!/bin/bash
# Check how zod is being used in mail.ts since it appeared in the search results
cat "apps/api/app/api/[[...route]]/mail.ts"

# Look for specific zod validator usage patterns
ast-grep --pattern 'import { $_ } from "@hono/zod-validator"'

# Check the contents of the API package.json to confirm zod dependencies
cat "apps/api/package.json"

Length of output: 2648

app
.get("/", async (c) => {
const user = await prisma.user.findMany();
return c.json({
user,
});
})
Comment on lines +4 to +10
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add error handling and authentication middleware to GET endpoint.

The GET endpoint has several issues:

  1. No error handling for database operations
  2. No pagination for potentially large result sets
  3. Missing authentication check for accessing user data

Consider implementing this structure:

 app
   .get("/", async (c) => {
+    try {
+      const page = parseInt(c.req.query('page') ?? '1');
+      const limit = parseInt(c.req.query('limit') ?? '10');
+      
       const user = await prisma.user.findMany({
+        take: limit,
+        skip: (page - 1) * limit
+      });
       return c.json({
-        user,
+        data: user,
+        page,
+        limit,
+        success: true
       });
+    } catch (error) {
+      return c.json({ 
+        success: false, 
+        error: 'Failed to fetch users' 
+      }, 500);
+    }
   })

Committable suggestion skipped: line range outside the PR's diff.

.patch(async (c) => {
const name = await c.req.json();
const test = await prisma.user.update({
where: {
id: "123",
},
data: {
name: name.name,
},
});
return c.json({
test,
});
})
Comment on lines +11 to +24
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: Remove hardcoded ID and add proper validation in PATCH endpoint.

Several critical issues in the PATCH endpoint:

  1. Hardcoded user ID "123"
  2. No validation of input data
  3. Direct assignment of user input without sanitization
  4. No error handling

Apply these changes:

-  .patch(async (c) => {
+  .patch("/:id", async (c) => {
+    try {
+      const userId = c.req.param('id');
       const name = await c.req.json();
+      
+      if (!name.name || typeof name.name !== 'string') {
+        return c.json({ 
+          success: false, 
+          error: 'Invalid name provided' 
+        }, 400);
+      }
+
       const test = await prisma.user.update({
         where: {
-          id: "123",
+          id: userId,
         },
         data: {
           name: name.name,
         },
       });
       return c.json({
-        test,
+        data: test,
+        success: true
       });
+    } catch (error) {
+      return c.json({ 
+        success: false, 
+        error: 'Failed to update user' 
+      }, 500);
+    }
   })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.patch(async (c) => {
const name = await c.req.json();
const test = await prisma.user.update({
where: {
id: "123",
},
data: {
name: name.name,
},
});
return c.json({
test,
});
})
.patch("/:id", async (c) => {
try {
const userId = c.req.param('id');
const name = await c.req.json();
if (!name.name || typeof name.name !== 'string') {
return c.json({
success: false,
error: 'Invalid name provided'
}, 400);
}
const test = await prisma.user.update({
where: {
id: userId,
},
data: {
name: name.name,
},
});
return c.json({
data: test,
success: true
});
} catch (error) {
return c.json({
success: false,
error: 'Failed to update user'
}, 500);
}
})

.delete(async (c) => {
const test = await prisma.user.delete({
where: {
id: "2",
},
});
return c.json({
test,
});
})
Comment on lines +25 to +34
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: Remove hardcoded ID and add proper error handling in DELETE endpoint.

The DELETE endpoint has similar issues:

  1. Hardcoded user ID "2"
  2. No authentication/authorization check
  3. No error handling

Apply these changes:

-  .delete(async (c) => {
+  .delete("/:id", async (c) => {
+    try {
+      const userId = c.req.param('id');
       const test = await prisma.user.delete({
         where: {
-          id: "2",
+          id: userId,
         },
       });
       return c.json({
-        test,
+        data: test,
+        success: true
       });
+    } catch (error) {
+      if (error.code === 'P2025') {
+        return c.json({ 
+          success: false, 
+          error: 'User not found' 
+        }, 404);
+      }
+      return c.json({ 
+        success: false, 
+        error: 'Failed to delete user' 
+      }, 500);
+    }
   })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.delete(async (c) => {
const test = await prisma.user.delete({
where: {
id: "2",
},
});
return c.json({
test,
});
})
.delete("/:id", async (c) => {
try {
const userId = c.req.param('id');
const test = await prisma.user.delete({
where: {
id: userId,
},
});
return c.json({
data: test,
success: true
});
} catch (error) {
if (error.code === 'P2025') {
return c.json({
success: false,
error: 'User not found'
}, 404);
}
return c.json({
success: false,
error: 'Failed to delete user'
}, 500);
}
})

.post(async (c) => {
const body = await c.req.json();
console.log(body);
const test = await prisma.user.create({
data: body,
});
return c.json({
test,
});
});
Comment on lines +35 to +44
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Critical: Remove console.log and add input validation in POST endpoint.

Issues in the POST endpoint:

  1. Debug console.log statement
  2. No validation of input data
  3. Direct passing of body to database
  4. No error handling

Apply these changes:

   .post(async (c) => {
+    try {
       const body = await c.req.json();
-      console.log(body);
+      
+      // Validate required fields
+      if (!body.email || !body.name) {
+        return c.json({ 
+          success: false, 
+          error: 'Email and name are required' 
+        }, 400);
+      }
+
       const test = await prisma.user.create({
         data: body,
       });
       return c.json({
-        test,
+        data: test,
+        success: true
       });
+    } catch (error) {
+      if (error.code === 'P2002') {
+        return c.json({ 
+          success: false, 
+          error: 'User already exists' 
+        }, 409);
+      }
+      return c.json({ 
+        success: false, 
+        error: 'Failed to create user' 
+      }, 500);
+    }
   })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.post(async (c) => {
const body = await c.req.json();
console.log(body);
const test = await prisma.user.create({
data: body,
});
return c.json({
test,
});
});
.post(async (c) => {
try {
const body = await c.req.json();
// Validate required fields
if (!body.email || !body.name) {
return c.json({
success: false,
error: 'Email and name are required'
}, 400);
}
const test = await prisma.user.create({
data: body,
});
return c.json({
data: test,
success: true
});
} catch (error) {
if (error.code === 'P2002') {
return c.json({
success: false,
error: 'User already exists'
}, 409);
}
return c.json({
success: false,
error: 'Failed to create user'
}, 500);
}
})


export default app;
62 changes: 62 additions & 0 deletions apps/api/app/api/[[...route]]/mail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { Hono } from "hono";
import { sendBatchEmail, sendEmail } from "@repo/mail";
import { mailBatchSchema, mailSchema } from "@repo/types";
import { zValidator } from "@hono/zod-validator";

const app = new Hono();

app
.post("/send", zValidator("json", mailSchema), async (c) => {
const { email, subject } = c.req.valid("json");
const { data, error } = await sendEmail(email, subject);
if (error) {
return c.json(
{
message: "Email sent failed",
},
400,
);
}
return c.json(
{
message: "Email sent successfully",
data,
},
200,
);
})
.get((c) => {
return c.json({
message: "mail api is alive",
status: 200,
});
});
Comment on lines +8 to +33
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add rate limiting and improve error handling for the email endpoint.

While the basic functionality is implemented correctly, consider the following security and observability improvements:

  1. Add rate limiting to prevent abuse
  2. Include specific error messages from the error object
  3. Add logging for monitoring and debugging
  4. Sanitize email content to prevent injection attacks

Here's a suggested improvement:

 app
+  .use("/send", rateLimiter({ max: 10, window: "10m" }))
   .post("/send", zValidator("json", mailSchema), async (c) => {
     const { email, subject } = c.req.valid("json");
+    const sanitizedSubject = sanitizeHtml(subject);
+    logger.info(`Sending email to ${email}`);
     const { data, error } = await sendEmail(email, sanitizedSubject);
     if (error) {
+      logger.error(`Email send failed: ${error.message}`);
       return c.json(
         {
-          message: "Email sent failed",
+          message: `Email send failed: ${error.message}`,
         },
         400,
       );
     }
+    logger.info(`Email sent successfully to ${email}`);
     return c.json(

Committable suggestion skipped: line range outside the PR's diff.


app
.post("/send-batch", zValidator("json", mailBatchSchema), async (c) => {
const { emails, subject } = c.req.valid("json");
const { data, error } = await sendBatchEmail(emails, subject);
if (error) {
return c.json(
{
message: "Email sent failed",
},
400,
);
}
return c.json(
{
message: "All Emails sent successfully",
data,
},
200,
);
})
.get((c) => {
return c.json({
message: "all mail api is alive",
status: 200,
});
});
Comment on lines +35 to +60
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Enhance batch email processing with limits and concurrent handling.

The batch endpoint needs additional safeguards and optimizations:

  1. Limit the maximum number of emails in a batch
  2. Implement concurrent processing for better performance
  3. Add detailed progress/status reporting

Here's a suggested improvement:

 app
   .post("/send-batch", zValidator("json", mailBatchSchema), async (c) => {
     const { emails, subject } = c.req.valid("json");
+    if (emails.length > 100) {
+      return c.json({ message: "Batch size exceeds maximum limit of 100" }, 400);
+    }
+    const sanitizedSubject = sanitizeHtml(subject);
+    logger.info(`Processing batch email to ${emails.length} recipients`);
-    const { data, error } = await sendBatchEmail(emails, subject);
+    const { data, error } = await Promise.all(
+      emails.map(email => sendEmail(email, sanitizedSubject))
+    );
     if (error) {
+      logger.error(`Batch email failed: ${error.message}`);
       return c.json(
         {
-          message: "Email sent failed",
+          message: `Batch email failed: ${error.message}`,
+          failedEmails: error.failed,
         },
         400,
       );
     }

Committable suggestion skipped: line range outside the PR's diff.


export default app;
121 changes: 81 additions & 40 deletions apps/api/app/api/[[...route]]/route.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,104 @@
import { prisma } from "@repo/db";
import { Hono } from "hono";
import { handle } from "hono/vercel";
import { Hono } from "hono";
import { auth } from "@repo/auth";
import { cors } from "hono/cors";
import mail from "./mail";
import hello from "./hello";

const allowedOrigins = [
"http://localhost:3003",
"https://www.plura.pro",
"http://app.plura.pro",
];

export const runtime = "nodejs";

const app = new Hono().basePath("/api");
const app = new Hono<{
Variables: {
user: typeof auth.$Infer.Session.user | null;
session: typeof auth.$Infer.Session.session | null;
};
}>().basePath("/api");

app
.get("/hello", async (c) => {
const test = await prisma.user.findMany();
return c.json({
test,
});
})
.patch(async (c) => {
const name = await c.req.json();
const test = await prisma.user.update({
where: {
id: "123",
},
data: {
name: name.name,
},
});
return c.json({
test,
});
})
.delete(async (c) => {
const test = await prisma.user.delete({
where: {
id: "2",
app.use(
"/auth/**",
cors({
origin: allowedOrigins,
allowHeaders: ["Content-Type", "Authorization"],
allowMethods: ["POST", "GET", "OPTIONS"],
exposeHeaders: ["Content-Length"],
maxAge: 600,
credentials: true,
}),
);
app.options("/auth/**", (c) => {
const origin = c.req.raw.headers.get("origin") ?? "";

if (allowedOrigins.includes(origin)) {
return new Response(null, {
status: 204,
headers: {
"Access-Control-Allow-Origin": origin,
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Credentials": "true",
"Access-Control-Max-Age": "600",
},
});
return c.json({
test,
});
})
.post(async (c) => {
const body = await c.req.json();
console.log(body);
const test = await prisma.user.create({
data: body,
});
return c.json({
test,
});
}

return new Response("Forbidden", {
status: 403,
});
});
app.use("*", async (c, next) => {
const session = await auth.api.getSession({ headers: c.req.raw.headers });

if (!session) {
c.set("user", null);
c.set("session", null);
return next();
}

c.set("user", session.user);
c.set("session", session.session);
return next();
});
Comment on lines +55 to +67
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for getSession call.

The middleware currently does not handle potential errors from auth.api.getSession. If an error occurs, it could lead to unhandled exceptions. Consider wrapping the getSession call in a try-catch block to handle any errors gracefully.

Apply this diff to add error handling:

 app.use("*", async (c, next) => {
+  try {
     const session = await auth.api.getSession({ headers: c.req.raw.headers });
 
     if (!session) {
       c.set("user", null);
       c.set("session", null);
       return next();
     }
 
     c.set("user", session.user);
     c.set("session", session.session);
     return next();
+  } catch (error) {
+    c.set("user", null);
+    c.set("session", null);
+    return next();
+  }
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
app.use("*", async (c, next) => {
const session = await auth.api.getSession({ headers: c.req.raw.headers });
if (!session) {
c.set("user", null);
c.set("session", null);
return next();
}
c.set("user", session.user);
c.set("session", session.session);
return next();
});
app.use("*", async (c, next) => {
try {
const session = await auth.api.getSession({ headers: c.req.raw.headers });
if (!session) {
c.set("user", null);
c.set("session", null);
return next();
}
c.set("user", session.user);
c.set("session", session.session);
return next();
} catch (error) {
c.set("user", null);
c.set("session", null);
return next();
}
});


app.get("/health", async (c) => {
return c.json({
message: "i am alive",
status: 200,
});
});
app.get("/session", async (c) => {
const session = c.get("session");
const user = c.get("user");

if (!user) return c.body(null, 401);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Correct response method for unauthorized access.

The method c.body(null, 401) may not correctly send a 401 Unauthorized response. In Hono, you should use c.text() or c.json() to send responses with status codes. Apply this diff to fix the issue:

-  if (!user) return c.body(null, 401);
+  if (!user) return c.text('Unauthorized', 401);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!user) return c.body(null, 401);
if (!user) return c.text('Unauthorized', 401);


return c.json({
session,
user,
});
});
app.route("/hello", hello);
app.route("/mail", mail);

app.on(["POST", "GET"], "/auth/**", (c) => {
return auth.handler(c.req.raw);
});
app.get("/multi-sessions", async (c) => {
const res = await auth.api.listDeviceSessions({
headers: c.req.raw.headers,
});
return c.json(res);
});
const GET = handle(app);
const POST = handle(app);
const PATCH = handle(app);
const DELETE = handle(app);
export const OPTIONS = handle(app);

export { GET, PATCH, POST, DELETE };
8 changes: 6 additions & 2 deletions apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,21 @@
"format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache"
},
"dependencies": {
"@hono/node-server": "^1.13.5",
"@hono/zod-validator": "^0.4.1",
"@repo/auth": "workspace:*",
"@repo/db": "workspace:*",
"contentlayer2": "^0.5.3",
"hono": "^4.6.9",
"next": "15.0.2",
"react": "19.0.0-rc-02c0e824-20241028",
"react-dom": "19.0.0-rc-02c0e824-20241028"
"react-dom": "19.0.0-rc-02c0e824-20241028",
"zod": "^3.23.8"
},
"devDependencies": {
"@types/node": "18.11.18",
"@types/react": "18.0.26",
"@types/react-dom": "18.0.10",
"dotenv": "^16.4.5",
"typescript": "^5"
}
}
10 changes: 6 additions & 4 deletions apps/api/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "NodeNext",
"moduleResolution": "NodeNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
Expand All @@ -34,8 +34,10 @@
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
".next/types/**/*.ts",
"src/**/*.ts",
"src/**/*.d.ts"
, "../../packages/types/auth.ts" ],
"exclude": [
"node_modules"
]
Expand Down
1 change: 0 additions & 1 deletion apps/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
"next": "15.0.2",
"next-themes": "^0.4.3",
"react": "19.0.0-rc-02c0e824-20241028",
"react-beautiful-dnd": "^13.1.1",
"react-dom": "19.0.0-rc-02c0e824-20241028",
"react-hook-form": "^7.53.1",
"recharts": "^2.13.3",
Expand Down
14 changes: 14 additions & 0 deletions apps/www/app/(auth)/dashboard/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import AccountSwitcher from "@/components/custom/account-switcher";
import { getMultipleSessions, getSession } from "@/lib/server";

export default async function page() {
const session = await getSession();
const multipleSessions = await getMultipleSessions();
return (
Comment on lines +4 to +7
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add error handling for API calls.

The component makes two API calls without any error handling. Failed API calls could crash the entire page.

 export default async function page() {
-  const session = await getSession();
-  const multipleSessions = await getMultipleSessions();
+  try {
+    const [session, multipleSessions] = await Promise.all([
+      getSession(),
+      getMultipleSessions(),
+    ]);
+    return (
+      <div>
+        <AccountSwitcher session={multipleSessions} activeSession={session} />
+        <pre className="font-sm">{JSON.stringify(session, null, 1)}</pre>
+      </div>
+    );
+  } catch (error) {
+    console.error('Failed to fetch session data:', error);
+    return <div>Failed to load dashboard. Please try again later.</div>;
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export default async function page() {
const session = await getSession();
const multipleSessions = await getMultipleSessions();
return (
export default async function page() {
try {
const [session, multipleSessions] = await Promise.all([
getSession(),
getMultipleSessions(),
]);
return (
<div>
<AccountSwitcher session={multipleSessions} activeSession={session} />
<pre className="font-sm">{JSON.stringify(session, null, 1)}</pre>
</div>
);
} catch (error) {
console.error('Failed to fetch session data:', error);
return <div>Failed to load dashboard. Please try again later.</div>;
}

<div>
<AccountSwitcher session={multipleSessions} activeSession={session} />
<pre className="font-sm">{JSON.stringify(session, null, 1)}</pre>
{/* <pre>{JSON.stringify(multipleSessions,null,2)}</pre> */}
Comment on lines +10 to +11
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security concern: Avoid displaying raw session data.

Displaying raw session data in the UI could expose sensitive information. Consider showing only necessary user information.

-      <pre className="font-sm">{JSON.stringify(session, null, 1)}</pre>
+      {session?.user && (
+        <div className="text-sm">
+          Logged in as: {session.user.email}
+        </div>
+      )}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<pre className="font-sm">{JSON.stringify(session, null, 1)}</pre>
{/* <pre>{JSON.stringify(multipleSessions,null,2)}</pre> */}
{session?.user && (
<div className="text-sm">
Logged in as: {session.user.email}
</div>
)}
{/* <pre>{JSON.stringify(multipleSessions,null,2)}</pre> */}

</div>
);
}
10 changes: 10 additions & 0 deletions apps/www/app/(auth)/sign-in/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import SignIn from "@/components/custom/Sign-In";

export default function page() {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Rename component to follow React naming convention.

React components should use PascalCase naming. Rename page to SignInPage to follow the convention.

-export default function page() {
+export default function SignInPage() {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export default function page() {
export default function SignInPage() {

return (
<div className="w-full h-screen flex items-center justify-center">
{" "}
<SignIn />
</div>
);
}
9 changes: 9 additions & 0 deletions apps/www/app/(auth)/sign-up/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import SignUp from "../../../components/custom/Sign-up";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix import path and component naming inconsistency.

The import statement has two issues:

  1. The relative import path (../../../) is fragile and could break if components are moved.
  2. The component filename uses inconsistent casing ("Sign-up" instead of "SignUp").

Consider these improvements:

-import SignUp from "../../../components/custom/Sign-up";
+import { SignUp } from "@/components/auth/SignUp";

Also, rename the component file from Sign-up.tsx to SignUp.tsx for consistency.

Committable suggestion skipped: line range outside the PR's diff.


export default function page() {
return (
<div className="w-full h-screen flex items-center justify-center">
<SignUp />
</div>
);
}
Loading