From 5de0c464f08d28c26e2e3db66b05d8296f00a893 Mon Sep 17 00:00:00 2001 From: Mythie Date: Thu, 23 Nov 2023 13:57:08 +1100 Subject: [PATCH 1/2] fix: hydration errors for modifier key --- .../components/(dashboard)/layout/desktop-nav.tsx | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/web/src/components/(dashboard)/layout/desktop-nav.tsx b/apps/web/src/components/(dashboard)/layout/desktop-nav.tsx index 01bdec657..76077cb04 100644 --- a/apps/web/src/components/(dashboard)/layout/desktop-nav.tsx +++ b/apps/web/src/components/(dashboard)/layout/desktop-nav.tsx @@ -1,7 +1,7 @@ 'use client'; import type { HTMLAttributes } from 'react'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { Search } from 'lucide-react'; @@ -15,11 +15,14 @@ export type DesktopNavProps = HTMLAttributes; export const DesktopNav = ({ className, ...props }: DesktopNavProps) => { // const pathname = usePathname(); const [open, setOpen] = useState(false); + const [modifierKey, setModifierKey] = useState(() => 'Ctrl'); - const userAgent = typeof navigator !== 'undefined' ? navigator.userAgent : 'unknown'; + useEffect(() => { + const userAgent = typeof navigator !== 'undefined' ? navigator.userAgent : 'unknown'; + const isMacOS = /Macintosh|Mac\s+OS\s+X/i.test(userAgent); - const isMacOS = /Macintosh|Mac\s+OS\s+X/i.test(userAgent); - const modifierKey = isMacOS ? '⌘' : 'Ctrl'; + setModifierKey(isMacOS ? '⌘' : 'Ctrl'); + }, []); return (
{
-
+
{modifierKey}+K
From c054fc78a490302c7b05224a8b459ff8c1cdc019 Mon Sep 17 00:00:00 2001 From: Mythie Date: Thu, 23 Nov 2023 15:11:37 +1100 Subject: [PATCH 2/2] fix: resolve issues with emailVerified jwt property --- packages/lib/next-auth/auth-options.ts | 25 ++++++++++++++++--------- packages/lib/types/next-auth.d.ts | 5 +++-- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/lib/next-auth/auth-options.ts b/packages/lib/next-auth/auth-options.ts index 216962293..57a37d7fe 100644 --- a/packages/lib/next-auth/auth-options.ts +++ b/packages/lib/next-auth/auth-options.ts @@ -1,9 +1,12 @@ +/// import { PrismaAdapter } from '@next-auth/prisma-adapter'; import { compare } from 'bcrypt'; import { DateTime } from 'luxon'; -import { AuthOptions, Session, User } from 'next-auth'; +import type { AuthOptions, Session, User } from 'next-auth'; +import type { JWT } from 'next-auth/jwt'; import CredentialsProvider from 'next-auth/providers/credentials'; -import GoogleProvider, { GoogleProfile } from 'next-auth/providers/google'; +import type { GoogleProfile } from 'next-auth/providers/google'; +import GoogleProvider from 'next-auth/providers/google'; import { prisma } from '@documenso/prisma'; @@ -48,6 +51,7 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = { id: Number(user.id), email: user.email, name: user.name, + emailVerified: user.emailVerified?.toISOString() ?? null, } satisfies User; }, }), @@ -61,6 +65,7 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = { id: Number(profile.sub), name: profile.name || `${profile.given_name} ${profile.family_name}`.trim(), email: profile.email, + emailVerified: profile.email_verified ? new Date().toISOString() : null, }; }, }), @@ -70,9 +75,10 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = { const merged = { ...token, ...user, - }; + emailVerified: user?.emailVerified ? new Date(user.emailVerified).toISOString() : null, + } satisfies JWT; - if (!merged.email) { + if (!merged.email || typeof merged.emailVerified !== 'string') { const userId = Number(merged.id ?? token.sub); const retrieved = await prisma.user.findFirst({ @@ -88,7 +94,7 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = { merged.id = retrieved.id; merged.name = retrieved.name; merged.email = retrieved.email; - merged.emailVerified = retrieved.emailVerified; + merged.emailVerified = retrieved.emailVerified?.toISOString() ?? null; } if ( @@ -98,7 +104,7 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = { ) { merged.lastSignedIn = new Date().toISOString(); - await prisma.user.update({ + const user = await prisma.user.update({ where: { id: Number(merged.id), }, @@ -106,6 +112,8 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = { lastSignedIn: merged.lastSignedIn, }, }); + + merged.emailVerified = user.emailVerified?.toISOString() ?? null; } return { @@ -114,7 +122,7 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = { email: merged.email, lastSignedIn: merged.lastSignedIn, emailVerified: merged.emailVerified, - }; + } satisfies JWT; }, session({ token, session }) { @@ -125,8 +133,7 @@ export const NEXT_AUTH_OPTIONS: AuthOptions = { id: Number(token.id), name: token.name, email: token.email, - emailVerified: - typeof token.emailVerified === 'string' ? new Date(token.emailVerified) : null, + emailVerified: token.emailVerified ?? null, }, } satisfies Session; } diff --git a/packages/lib/types/next-auth.d.ts b/packages/lib/types/next-auth.d.ts index 102678ef5..edc05ccc4 100644 --- a/packages/lib/types/next-auth.d.ts +++ b/packages/lib/types/next-auth.d.ts @@ -6,11 +6,11 @@ declare module 'next-auth' { user: User; } - interface User extends Omit { + interface User extends Omit { id: PrismaUser['id']; name?: PrismaUser['name']; email?: PrismaUser['email']; - emailVerified?: PrismaUser['emailVerified']; + emailVerified?: string | null; } } @@ -19,6 +19,7 @@ declare module 'next-auth/jwt' { id: string | number; name?: string | null; email: string | null; + emailVerified?: string | null; lastSignedIn?: string | null; } }