diff --git a/src/app/[lang]/(protected)/profile/page.tsx b/src/app/[lang]/(protected)/profile/page.tsx index d9c73ccc..8726e7b9 100644 --- a/src/app/[lang]/(protected)/profile/page.tsx +++ b/src/app/[lang]/(protected)/profile/page.tsx @@ -37,7 +37,7 @@ export default async function Profile({ - + ) diff --git a/src/app/[lang]/(protected)/profile/see-details-toggle.tsx b/src/app/[lang]/(protected)/profile/see-details-toggle.tsx index 8fbd965c..9861b2c2 100644 --- a/src/app/[lang]/(protected)/profile/see-details-toggle.tsx +++ b/src/app/[lang]/(protected)/profile/see-details-toggle.tsx @@ -1,9 +1,16 @@ +import { Session } from "next-auth" import ProfileDetails from "@/components/profile/profile-details" import UserActiveSessions from "@/components/profile/sessions/user-active-sessions" import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion" import { TDictionary } from "@/lib/langs" -export default function SeeDetailsToggle({ dictionary }: { dictionary: TDictionary }) { +export default function SeeDetailsToggle({ + dictionary, + session, +}: { + dictionary: TDictionary + session: Session | null +}) { return (
@@ -12,7 +19,7 @@ export default function SeeDetailsToggle({ dictionary }: { dictionary: TDictiona {dictionary.profilePage.profileDetails.toggle} - + diff --git a/src/components/profile/sessions/sessions-table.tsx b/src/components/profile/sessions/sessions-table.tsx index e8cfa0e8..d1371617 100644 --- a/src/components/profile/sessions/sessions-table.tsx +++ b/src/components/profile/sessions/sessions-table.tsx @@ -23,7 +23,7 @@ import SessionRow from "./session-row" const itemsPerPageInitial = 5 -export default function SessionsTable({ dictionary }: { dictionary: TDictionary }) { +export default function SessionsTable({ dictionary, isDisabled }: { dictionary: TDictionary; isDisabled?: boolean }) { const router = useRouter() const utils = trpc.useContext() @@ -35,7 +35,9 @@ export default function SessionsTable({ dictionary }: { dictionary: TDictionary page: currentPage, perPage: itemsPerPage, } - const activeSessions = useActiveSessions(dictionary, callParams) + const activeSessions = useActiveSessions(dictionary, callParams, { + disabled: isDisabled, + }) const [meta, setMeta] = useState(activeSessions.data?.meta) useEffect(() => { @@ -81,7 +83,7 @@ export default function SessionsTable({ dictionary }: { dictionary: TDictionary const showPagination = Boolean((meta && meta.totalPages > 1) || itemsPerPageInitial !== itemsPerPage) return ( -
+
{activeSessions.isFetched ? rows : skelRows} + {isDisabled && ( +
+

{dictionary.profilePage.unavailableWithOAuth}

+
+ )}
) } diff --git a/src/components/profile/sessions/user-active-sessions.tsx b/src/components/profile/sessions/user-active-sessions.tsx index 086a2a97..7cb4bc5c 100644 --- a/src/components/profile/sessions/user-active-sessions.tsx +++ b/src/components/profile/sessions/user-active-sessions.tsx @@ -1,24 +1,14 @@ +import { Session } from "next-auth" import { TDictionary } from "@/lib/langs" import SessionsTable from "./sessions-table" -/* -...dictionary.profilePage.profileDetails, - sessionTable: { - areYouAbsolutelySure: dictionary.areYouAbsolutelySure, - cancel: dictionary.cancel, - continue: dictionary.continue, - deleteLoggedDevice: dictionary.profilePage.profileDetails.deleteLoggedDevice, - session: dictionary.profilePage.profileDetails.session, - sessions: dictionary.profilePage.profileDetails.sessions, - error: dictionary.error, - delete: dictionary.delete, - fetch: dictionary.fetch, - couldNotMessage: dictionary.couldNotMessage, - }, - }} -*/ - -export default function UserActiveSessions({ dictionary }: { dictionary: TDictionary }) { +export default async function UserActiveSessions({ + dictionary, + session, +}: { + dictionary: TDictionary + session: Session | null +}) { return (
@@ -27,7 +17,7 @@ export default function UserActiveSessions({ dictionary }: { dictionary: TDictio {dictionary.profilePage.profileDetails.loggedDevicesDescription}

- +
) } diff --git a/src/contexts/active-sessions.tsx b/src/contexts/active-sessions.tsx index 897bd5ed..6d621087 100644 --- a/src/contexts/active-sessions.tsx +++ b/src/contexts/active-sessions.tsx @@ -10,11 +10,13 @@ export function useActiveSessions( params: Parameters["0"] = {}, extendedOptions?: { initialData?: z.infer> + disabled?: boolean } ) { const router = useRouter() const activeSessionsQuery = trpc.me.getActiveSessions.useQuery(params, { initialData: extendedOptions?.initialData, + enabled: !(extendedOptions?.disabled ?? false), onError(error) { handleQueryError(error, dictionary, router) }, diff --git a/src/langs/en.json b/src/langs/en.json index e6694239..796cbafc 100644 --- a/src/langs/en.json +++ b/src/langs/en.json @@ -32,7 +32,8 @@ "created": "Created", "expires": "Expires", "in": "in" - } + }, + "unavailableWithOAuth": "This feature is not available with OAuth providers." }, "auth": { "orContinueWith": "Or continue with", diff --git a/src/langs/fr.json b/src/langs/fr.json index 20573fe2..661395bc 100644 --- a/src/langs/fr.json +++ b/src/langs/fr.json @@ -32,7 +32,8 @@ "created": "Créé", "expires": "Expire", "in": "dans" - } + }, + "unavailableWithOAuth": "Cette fonctionnalité n'est pas disponible avec ce type de connexion." }, "auth": { "orContinueWith": "Ou continuez avec", diff --git a/src/lib/auth/index.ts b/src/lib/auth/index.ts index 877dc428..6ab0882c 100644 --- a/src/lib/auth/index.ts +++ b/src/lib/auth/index.ts @@ -34,7 +34,7 @@ export const nextAuthOptions: NextAuthOptions & { }, authorize: async (credentials, req) => { const referer = (req.headers?.referer as string | undefined) ?? "" - const refererUrl = ensureRelativeUrl(referer) ?? "" + const refererUrl = ensureRelativeUrl(referer) const lang = i18n.locales.find((locale) => refererUrl.startsWith(`/${locale}/`)) ?? i18n.defaultLocale const dictionary = nextAuthOptions.loadedDictionary.get(lang) ?? @@ -127,6 +127,7 @@ export const nextAuthOptions: NextAuthOptions & { if (isPossiblyUndefined(user)) { token.id = user.id token.email = user.email + if ("hasPassword" in user) token.hasPassword = user.hasPassword as boolean if ("username" in user) token.username = user.username if ("role" in user) token.role = user.role as string if ("uuid" in user) token.uuid = user.uuid as string @@ -154,6 +155,11 @@ export const nextAuthOptions: NextAuthOptions & { } //* Verify that the session still exists + if (dbUser.hasPassword && (!token.uuid || typeof token.uuid !== "string")) { + logger.debug("Missing token uuid") + return {} as Session + } + if (token.uuid) { const loginSession = await prisma.session.findUnique({ where: { @@ -179,6 +185,7 @@ export const nextAuthOptions: NextAuthOptions & { //* Fill session with user data const username = dbUser.username const role = dbUser.role + const hasPassword = dbUser.hasPassword //* Fill session with token data const uuid = "uuid" in token ? token.uuid : undefined @@ -191,6 +198,7 @@ export const nextAuthOptions: NextAuthOptions & { username: username ?? undefined, role, uuid, + hasPassword, }, } return sessionFilled diff --git a/types.d.ts b/types.d.ts index 988127c7..88486ed5 100644 --- a/types.d.ts +++ b/types.d.ts @@ -8,6 +8,7 @@ declare module "next-auth" { uuid: string username?: string role: string + hasPassword: boolean } } } @@ -16,6 +17,7 @@ declare module "next-auth/jwt/types" { interface JWT { uuid: string role: string + hasPassword: boolean } }