-
Notifications
You must be signed in to change notification settings - Fork 1.3k
fix: Move all extra Microsoft Auth data to the database #609
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
Merged
elie222
merged 11 commits into
elie222:main
from
edulelis:fix-microsoft-auth-large-cookies
Jul 31, 2025
+41
−23
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
a3523de
Reduce cookies, removing avatar and tokens
edulelis fe82b39
Cleanup code and comments
edulelis b2df26f
Move only picture and user objects to db
edulelis 23d3b9e
Fix new users not being created
edulelis 7e953cb
Comment cleanup
edulelis 37796c4
Restore Gmail comments
edulelis caf1289
Removing signin callback
edulelis c0bfd13
Simplify session block
edulelis 5be06b8
Reduce and simplify code
edulelis e8ee25a
Remove unused vars. Revert removed comment
edulelis 0c3460e
Update comments
edulelis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| // based on: https://github.com/vercel/platforms/blob/main/lib/auth.ts | ||
| import { PrismaAdapter } from "@auth/prisma-adapter"; | ||
| import type { Prisma } from "@prisma/client"; | ||
| import type { NextAuthConfig, DefaultSession } from "next-auth"; | ||
| import type { NextAuthConfig, DefaultSession, Session, User } from "next-auth"; | ||
| import { cookies } from "next/headers"; | ||
| import type { JWT } from "@auth/core/jwt"; | ||
| import GoogleProvider from "next-auth/providers/google"; | ||
|
|
@@ -218,6 +218,7 @@ export const getAuthOptions: () => NextAuthConfig = () => ({ | |
| // On future log ins, we retrieve the `refresh_token` from the database | ||
| if (account.refresh_token) { | ||
| logger.info("Saving refresh token", { email: token.email }); | ||
|
|
||
| await saveTokens({ | ||
| tokens: { | ||
| access_token: account.access_token, | ||
|
|
@@ -230,6 +231,7 @@ export const getAuthOptions: () => NextAuthConfig = () => ({ | |
| providerAccountId: account.providerAccountId, | ||
| provider: account.provider, | ||
| }); | ||
|
|
||
| token.refresh_token = account.refresh_token; | ||
| } else { | ||
| const dbAccount = await prisma.account.findUnique({ | ||
|
|
@@ -244,36 +246,31 @@ export const getAuthOptions: () => NextAuthConfig = () => ({ | |
| token.refresh_token = dbAccount?.refresh_token ?? undefined; | ||
| } | ||
|
|
||
| token.provider = account.provider; | ||
| token.access_token = account.access_token; | ||
| token.refresh_token = account.refresh_token; | ||
| token.expires_at = account.expires_at; | ||
| token.user = user; | ||
| token.provider = account.provider; | ||
|
|
||
| if (account.provider === "microsoft-entra-id") { | ||
| token.name = user.name; | ||
| token.email = user.email; | ||
| // These fields shouldn't be in the JWT because the cookie will be too large | ||
| // They are stored in the database instead | ||
| token.picture = undefined; | ||
| token.user = undefined; | ||
| } else { | ||
| token.user = user; | ||
| } | ||
| return token; | ||
| } | ||
|
|
||
| // logger.info("JWT callback - current token state", { | ||
| // email: token.email, | ||
| // currentExpiresAt: token.expires_at | ||
| // ? new Date((token.expires_at as number) * 1000).toISOString() | ||
| // : "not set", | ||
| // }); | ||
|
|
||
| if ( | ||
| token.expires_at && | ||
| Date.now() < (token.expires_at as number) * 1000 | ||
| ) { | ||
| // // If the access token has not expired yet, return it | ||
| // logger.info("Token still valid", { | ||
| // email: token.email, | ||
| // expiresIn: | ||
| // ((token.expires_at as number) * 1000 - Date.now()) / 1000 / 60, | ||
| // minutes: true, | ||
| // }); | ||
| return token; | ||
| } | ||
|
|
||
| // If the access token has expired, try to refresh it | ||
| logger.info("Token expired at", { | ||
| email: token.email, | ||
| expiresAt: token.expires_at | ||
|
|
@@ -289,15 +286,36 @@ export const getAuthOptions: () => NextAuthConfig = () => ({ | |
| }); | ||
| return refreshedToken; | ||
| }, | ||
| session: async ({ session, token }) => { | ||
| session: async ({ session, token }: { session: Session; token: JWT }) => { | ||
| session.user = { | ||
| ...session.user, | ||
| id: token.sub as string, | ||
| id: token.sub || "", | ||
| }; | ||
|
|
||
| if (token.provider === "microsoft-entra-id") { | ||
| const user = await prisma.user.findUnique({ | ||
| where: { id: token.sub || "" }, | ||
| select: { | ||
| id: true, | ||
| email: true, | ||
| name: true, | ||
| image: true, | ||
| }, | ||
| }); | ||
|
|
||
| if (user) { | ||
| session.user = { | ||
| id: user.id, | ||
| email: user.email, | ||
| name: user.name, | ||
| image: user.image, | ||
| }; | ||
| } | ||
| } | ||
|
Comment on lines
+295
to
+314
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do we need image in the session though? we'll just fetch the image when we actually need it. are you sure we need this db call at all? |
||
|
|
||
| // based on: https://github.com/nextauthjs/next-auth/issues/1162#issuecomment-766331341 | ||
| session.accessToken = token?.access_token as string | undefined; | ||
| session.error = token?.error as string | undefined; | ||
| session.accessToken = token.access_token; | ||
| session.error = token.error; | ||
|
|
||
| if (session.error) { | ||
| logger.error("session.error", { | ||
|
|
@@ -310,7 +328,7 @@ export const getAuthOptions: () => NextAuthConfig = () => ({ | |
| }, | ||
| }, | ||
| events: { | ||
| signIn: async ({ isNewUser, user }) => { | ||
| signIn: async ({ isNewUser, user }: { isNewUser?: boolean; user: User }) => { | ||
| if (isNewUser && user.email) { | ||
| const [loopsResult, resendResult, dubResult] = await Promise.allSettled( | ||
| [ | ||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.