From 735f830251d6571f40e675a9cd08c51648aeff0e Mon Sep 17 00:00:00 2001 From: Pablo Lara Date: Sat, 5 Oct 2024 14:02:22 +0200 Subject: [PATCH] feat: add function getUserByMe --- actions/auth/auth.ts | 34 +++++++++++++++++++- auth.config.ts | 74 ++++++++++++++++++++++++-------------------- nextauth.d.ts | 22 ++++++++----- 3 files changed, 89 insertions(+), 41 deletions(-) diff --git a/actions/auth/auth.ts b/actions/auth/auth.ts index 6f3cae0376..28504d2c0c 100644 --- a/actions/auth/auth.ts +++ b/actions/auth/auth.ts @@ -77,7 +77,7 @@ export const getToken = async (formData: z.infer) => { if (!response.ok) return null; const parsedResponse = await response.json(); - // return parsedResponse; + const accessToken = parsedResponse.data.attributes.access; const refreshToken = parsedResponse.data.attributes.refresh; return { @@ -89,6 +89,38 @@ export const getToken = async (formData: z.infer) => { } }; +export const getUserByMe = async (accessToken: string) => { + const keyServer = process.env.API_BASE_URL; + const url = new URL(`${keyServer}/users/me`); + + try { + const response = await fetch(url.toString(), { + method: "GET", + headers: { + Accept: "application/vnd.api+json", + Authorization: `Bearer ${accessToken}`, + }, + }); + + if (!response.ok) throw new Error("Error in trying to get user by me"); + + const parsedResponse = await response.json(); + + const name = parsedResponse.data.attributes.name; + const email = parsedResponse.data.attributes.email; + const company = parsedResponse.data.attributes.company_name; + const dateJoined = parsedResponse.data.attributes.date_joined; + return { + name, + email, + company, + dateJoined, + }; + } catch (error) { + throw new Error("Error in trying to get user by me"); + } +}; + export async function logOut() { await signOut(); } diff --git a/auth.config.ts b/auth.config.ts index d62704e913..2370fe02bb 100644 --- a/auth.config.ts +++ b/auth.config.ts @@ -1,22 +1,16 @@ -import { jwtDecode } from "jwt-decode"; -import NextAuth, { type NextAuthConfig } from "next-auth"; -import { DefaultSession } from "next-auth"; +import { jwtDecode, JwtDecodeOptions, JwtPayload } from "jwt-decode"; +import NextAuth, { type NextAuthConfig, User } from "next-auth"; import Credentials from "next-auth/providers/credentials"; import { z } from "zod"; import { getToken } from "./actions/auth"; -import { CustomJwtPayload } from "./types"; -import { UserAttributes } from "./types/users"; -declare module "next-auth" { - interface Session extends DefaultSession { - accessToken: string; - refreshToken: string; - user: UserAttributes; - } +interface CustomJwtPayload extends JwtPayload { + user_id: string; + tenant_id: string; } -const refreshAccessToken = async (token: CustomJwtPayload) => { +const refreshAccessToken = async (token: JwtDecodeOptions) => { const keyServer = process.env.API_BASE_URL; const url = new URL(`${keyServer}/tokens/refresh`); @@ -42,7 +36,6 @@ const refreshAccessToken = async (token: CustomJwtPayload) => { const newTokens = await response.json(); if (!response.ok) { - // TODO: handle error throw new Error(`HTTP error! status: ${response.status}`); } @@ -115,53 +108,68 @@ export const authConfig = { }, jwt: async ({ token, account, user }) => { - // console.log(`In the jwt token - is ${JSON.stringify(token)}`); + // eslint-disable-next-line no-console + console.log(`In the jwt token - is ${JSON.stringify(token)}`); if (token?.accessToken) { - const decodedToken = jwtDecode(token.accessToken); + const decodedToken = jwtDecode( + token.accessToken as string, + ) as CustomJwtPayload; + // eslint-disable-next-line no-console console.log("decodedToken", decodedToken); - - token.accessTokenExpires = decodedToken?.exp * 1000; + token.accessTokenExpires = (decodedToken.exp as number) * 1000; + token.user_id = decodedToken.user_id; + token.tenant_id = decodedToken.tenant_id; } + const userInfo = { + name: "Leandro", + companyName: "Bitnami", + email: "john@doe.com", + date_joined: "2024-02-02", + }; + if (account && user) { - // token.data = user; return { ...token, - accessToken: user.accessToken, - refreshToken: user.refreshToken, - user: { - id: "123", - tenantId: "123", - name: "John", - companyName: "Doe", - email: "john@doe.com", - date_joined: "2024-02-02", - }, + userId: token.user_id, + tenantId: token.tenant_id, + accessToken: (user as User & { accessToken: JwtPayload }).accessToken, + refreshToken: (user as User & { refreshToken: JwtPayload }) + .refreshToken, + user: userInfo, }; } + // eslint-disable-next-line no-console console.log( "Access token expires", token.accessTokenExpires, new Date(Number(token.accessTokenExpires)), ); - if (Date.now() < token.accessTokenExpires) return token; + // If the access token is not expired, return the token + if ( + typeof token.accessTokenExpires === "number" && + Date.now() < token.accessTokenExpires + ) + return token; - // Access token is expired, we need to refresh it - return refreshAccessToken(token); + // If the access token is expired, try to refresh it + return refreshAccessToken(token as unknown as JwtDecodeOptions); }, session: async ({ session, token }) => { // session.user = token.data; if (token) { + session.userId = token?.user_id as string; + session.tenantId = token?.tenant_id as string; session.accessToken = token?.accessToken as string; session.refreshToken = token?.refreshToken as string; - session.user = token.user; + session.user = token.user as any; } - // console.log("session", session); + console.log("session", session); return session; }, }, diff --git a/nextauth.d.ts b/nextauth.d.ts index 2fe2480ce5..e4eaa51f8a 100644 --- a/nextauth.d.ts +++ b/nextauth.d.ts @@ -1,15 +1,23 @@ import { DefaultSession } from "next-auth"; declare module "next-auth" { - interface Session { + interface User extends NextAuthUser { + name: string; + email: string; + company?: string; + dateJoined: string; + } + + interface Session extends DefaultSession { user: { - id: string; - tenantId: string; - firstName: string; - companyName: string; + name: string; email: string; - role: string; - image?: string; + company?: string; + dateJoined: string; } & DefaultSession["user"]; + userId: string; + tenantId: string; + accessToken: string; + refreshToken: string; } }