From c7fc01b7820945cddf169cc99d0a4613fb6e16a6 Mon Sep 17 00:00:00 2001 From: mARTin Date: Tue, 3 Mar 2026 14:03:09 +0100 Subject: [PATCH] Add Microsoft Auth and update Auth UI --- README.md | 2 ++ package-lock.json | 11 +++++++++++ package.json | 1 + src/app/auth/login/page.tsx | 20 +++++++++++++++++++- src/app/auth/signup/page.tsx | 20 +++++++++++++++++++- src/app/globals.css | 9 ++++++++- src/lib/auth.ts | 21 ++++++++++++++++++--- 7 files changed, 78 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9f97396..647574f 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,8 @@ The application requires the following environment variables: - `DATABASE_URL`: PostgreSQL connection string - `NEXTAUTH_SECRET`: Secret for NextAuth.js - `NEXT_PUBLIC_BASE_URL`: Public URL of the application +- `MICROSOFT_CLIENT_ID`: Azure AD Application (client) ID for Microsoft Login +- `MICROSOFT_CLIENT_SECRET`: Azure AD Application secret for Microsoft Login ### Database Configuration diff --git a/package-lock.json b/package-lock.json index 2701f39..5426118 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "license": "MIT", "dependencies": { "@auth/prisma-adapter": "^2.11.1", + "@next-auth/prisma-adapter": "^1.0.7", "@prisma/client": "^5.22.0", "@types/bcryptjs": "^2.4.6", "@types/nodemailer": "^7.0.11", @@ -1955,6 +1956,16 @@ "@tybys/wasm-util": "^0.10.0" } }, + "node_modules/@next-auth/prisma-adapter": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@next-auth/prisma-adapter/-/prisma-adapter-1.0.7.tgz", + "integrity": "sha512-Cdko4KfcmKjsyHFrWwZ//lfLUbcLqlyFqjd/nYE2m3aZ7tjMNUjpks47iw7NTCnXf+5UWz5Ypyt1dSs1EP5QJw==", + "license": "ISC", + "peerDependencies": { + "@prisma/client": ">=2.26.0 || >=3", + "next-auth": "^4" + } + }, "node_modules/@next/env": { "version": "14.2.35", "resolved": "https://registry.npmjs.org/@next/env/-/env-14.2.35.tgz", diff --git a/package.json b/package.json index c97e729..157fc51 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "license": "MIT", "dependencies": { "@auth/prisma-adapter": "^2.11.1", + "@next-auth/prisma-adapter": "^1.0.7", "@prisma/client": "^5.22.0", "@types/bcryptjs": "^2.4.6", "@types/nodemailer": "^7.0.11", diff --git a/src/app/auth/login/page.tsx b/src/app/auth/login/page.tsx index 239ac34..6a1195d 100644 --- a/src/app/auth/login/page.tsx +++ b/src/app/auth/login/page.tsx @@ -50,6 +50,10 @@ function LoginContent() { )} +

+ Recommended: Log in with email +

+ {/* Login Form */}
@@ -85,7 +89,7 @@ function LoginContent() { {/* Divider */}
- or + or trust US Big Tech
{/* Google Sign In */} @@ -118,6 +122,20 @@ function LoginContent() { Continue with Apple + {/* Microsoft Sign In */} + + {/* Links */}
diff --git a/src/app/auth/signup/page.tsx b/src/app/auth/signup/page.tsx index f713051..0265c7f 100644 --- a/src/app/auth/signup/page.tsx +++ b/src/app/auth/signup/page.tsx @@ -91,6 +91,10 @@ export default function SignupPage() {
)} +

+ Recommended: Sign up with email +

+ {/* Signup Form */}
@@ -150,7 +154,7 @@ export default function SignupPage() { {/* Divider */}
- or + or trust US Big Tech
{/* Google Sign Up */} @@ -183,6 +187,20 @@ export default function SignupPage() { Sign up with Apple + {/* Microsoft Sign Up */} + + {/* Links */}
Already have an account? diff --git a/src/app/globals.css b/src/app/globals.css index 6b99fb6..571f725 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -186,6 +186,14 @@ h3 { color: #64748b; } +.weekly-auth-recommended { + font-size: 0.85rem; + color: #475569; + text-align: center; + margin-bottom: 1rem; + font-weight: 500; +} + .time-indicator { font-size: 0.875rem; color: #3b82f6; @@ -330,7 +338,6 @@ h3 { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05); } -/* Auth Form */ .auth-form { background: white; border-radius: 8px; diff --git a/src/lib/auth.ts b/src/lib/auth.ts index 8da35ca..032f2a6 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -1,13 +1,14 @@ import { NextAuthOptions } from "next-auth"; import GoogleProvider from "next-auth/providers/google"; +import AzureADProvider from "next-auth/providers/azure-ad"; import AppleProvider from "next-auth/providers/apple"; -import { PrismaAdapter } from "@auth/prisma-adapter"; +import { PrismaAdapter } from "@next-auth/prisma-adapter"; import CredentialsProvider from "next-auth/providers/credentials"; import { compare } from "bcryptjs"; import { prisma } from "@/lib/prisma"; export const authOptions: NextAuthOptions = { - adapter: PrismaAdapter(prisma) as any, + adapter: PrismaAdapter(prisma), providers: [ GoogleProvider({ clientId: process.env.GOOGLE_CLIENT_ID || "", @@ -17,7 +18,8 @@ export const authOptions: NextAuthOptions = { params: { prompt: "consent", access_type: "offline", - response_type: "code" + response_type: "code", + scope: "openid profile email https://www.googleapis.com/auth/calendar https://www.googleapis.com/auth/calendar.events https://www.googleapis.com/auth/tasks" } } }), @@ -26,6 +28,18 @@ export const authOptions: NextAuthOptions = { clientSecret: process.env.APPLE_SECRET || "", allowDangerousEmailAccountLinking: true, }), + AzureADProvider({ + clientId: process.env.MICROSOFT_CLIENT_ID || "", + clientSecret: process.env.MICROSOFT_CLIENT_SECRET || "", + tenantId: "common", + allowDangerousEmailAccountLinking: true, + authorization: { + params: { + prompt: "consent", + scope: "openid profile email offline_access user.read Calendars.ReadWrite Tasks.ReadWrite" + } + }, + }), CredentialsProvider({ name: "credentials", credentials: { @@ -70,6 +84,7 @@ export const authOptions: NextAuthOptions = { } }) ], + debug: true, session: { strategy: "jwt" },