Skip to content

Commit b0ffafa

Browse files
committed
refactor: enhance authentication error handling and type definitions
- Introduced TypeScript interfaces for user and response structures to improve type safety in authentication logic. - Updated error handling to throw specific errors for missing user data and token during authentication. - Refactored user data extraction to utilize the new type definitions, ensuring consistent handling of user properties.
1 parent b974fcd commit b0ffafa

1 file changed

Lines changed: 43 additions & 16 deletions

File tree

frontend/src/auth.ts

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
import NextAuth from "next-auth";
22
import Credentials from "next-auth/providers/credentials";
33

4+
interface LoginApiUser {
5+
id: number | string;
6+
username: string;
7+
email: string;
8+
firstName?: string;
9+
lastName?: string;
10+
roles?: string[];
11+
permissions?: string[];
12+
profilePicture?: string | null;
13+
verified?: boolean;
14+
}
15+
16+
interface LoginApiResponse {
17+
success?: boolean;
18+
message?: string;
19+
user?: LoginApiUser;
20+
token?: string;
21+
}
22+
423
export const { handlers, signIn, signOut, auth } = NextAuth({
524
secret: process.env.AUTH_SECRET || process.env.NEXTAUTH_SECRET,
625
trustHost: true,
@@ -35,10 +54,10 @@ export const { handlers, signIn, signOut, auth } = NextAuth({
3554

3655
// Check if response is JSON before parsing
3756
const contentType = res.headers.get("content-type");
38-
let data: { success?: boolean; message?: string; user?: unknown };
39-
57+
let data: LoginApiResponse;
58+
4059
if (contentType && contentType.includes("application/json")) {
41-
data = await res.json();
60+
data = (await res.json()) as LoginApiResponse;
4261
} else {
4362
// Handle non-JSON responses (e.g. 401 from gateway, rate limit plain text)
4463
const text = await res.text();
@@ -50,31 +69,39 @@ export const { handlers, signIn, signOut, auth } = NextAuth({
5069

5170
if (!data.success || !res.ok) {
5271
const errorMessage = data.message || "Authentication failed";
53-
54-
if (errorMessage.toLowerCase().includes("verify") ||
72+
73+
if (errorMessage.toLowerCase().includes("verify") ||
5574
errorMessage.toLowerCase().includes("verification") ||
5675
errorMessage.toLowerCase().includes("email")) {
5776
throw new Error("EMAIL_VERIFICATION_REQUIRED");
5877
}
59-
78+
6079
if (errorMessage.toLowerCase().includes("invalid credentials") ||
6180
errorMessage.toLowerCase().includes("user not found")) {
6281
throw new Error("INVALID_CREDENTIALS");
6382
}
64-
83+
6584
throw new Error(errorMessage);
6685
}
6786

87+
const user = data.user;
88+
if (!user) {
89+
throw new Error("Authentication failed: no user data");
90+
}
91+
if (!data.token) {
92+
throw new Error("Authentication failed: no token");
93+
}
94+
6895
return {
69-
id: data.user.id.toString(),
70-
username: data.user.username,
71-
email: data.user.email,
72-
firstName: data.user.firstName,
73-
lastName: data.user.lastName,
74-
roles: data.user.roles || ["user"],
75-
permissions: data.user.permissions || [],
76-
profilePicture: data.user.profilePicture,
77-
verified: data.user.verified || false,
96+
id: user.id.toString(),
97+
username: user.username,
98+
email: user.email,
99+
firstName: user.firstName,
100+
lastName: user.lastName,
101+
roles: user.roles ?? ["user"],
102+
permissions: user.permissions ?? [],
103+
profilePicture: user.profilePicture ?? undefined,
104+
verified: user.verified ?? false,
78105
token: data.token,
79106
};
80107
} catch (error) {

0 commit comments

Comments
 (0)