courrier msft oauth

This commit is contained in:
alma 2025-05-02 09:28:49 +02:00
parent cb095ab7ee
commit ad7cf7514e
5 changed files with 151 additions and 4 deletions

3
.env
View File

@ -83,4 +83,5 @@ REDIS_PASSWORD=mySecretPassword
MICROSOFT_CLIENT_ID="afaffea5-4e10-462a-aa64-e73baf642c57"
MICROSOFT_CLIENT_SECRET="eIx8Q~N3ZnXTjTsVM3ECZio4G7t.BO6AYlD1-b2h"
MICROSOFT_REDIRECT_URI="https://lab.slm-lab.net/ms"
MICROSOFT_REDIRECT_URI="https://lab.slm-lab.net/ms"
MICROSOFT_TENANT_ID="cb4281a9-4a3e-4ff5-9a85-8425dd04e2b2"

View File

@ -8,6 +8,7 @@ export default function MicrosoftCallbackPage() {
const searchParams = useSearchParams();
const [status, setStatus] = useState<string>('Processing authentication...');
const [error, setError] = useState<string | null>(null);
const [errorDetails, setErrorDetails] = useState<string | null>(null);
useEffect(() => {
async function handleCallback() {
@ -16,9 +17,16 @@ export default function MicrosoftCallbackPage() {
const code = searchParams.get('code');
const state = searchParams.get('state');
const errorMsg = searchParams.get('error');
const errorDescription = searchParams.get('error_description');
if (errorMsg) {
setError(`Authentication error: ${errorMsg}`);
if (errorDescription) {
// URL decode the error description
const decodedErrorDescription = decodeURIComponent(errorDescription);
setErrorDetails(decodedErrorDescription);
console.error('Auth error details:', decodedErrorDescription);
}
return;
}
@ -42,6 +50,9 @@ export default function MicrosoftCallbackPage() {
if (!response.ok) {
setError(data.error || 'Failed to process authentication');
if (data.details) {
setErrorDetails(data.details);
}
return;
}
@ -69,6 +80,11 @@ export default function MicrosoftCallbackPage() {
<div className="p-4 bg-red-50 text-red-700 rounded-md">
<p className="font-medium">Error</p>
<p>{error}</p>
{errorDetails && (
<div className="mt-2 p-2 bg-red-100 rounded text-sm overflow-auto max-h-40">
<p>{errorDetails}</p>
</div>
)}
<button
onClick={() => router.push('/courrier')}
className="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"

View File

@ -1,14 +1,26 @@
import axios from 'axios';
// Microsoft OAuth URLs
const MICROSOFT_AUTHORIZE_URL = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
const MICROSOFT_TOKEN_URL = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
// Get tenant ID from env var or use a default
const tenantId = process.env.MICROSOFT_TENANT_ID || 'common'; // Use 'organizations' or actual tenant ID
// Microsoft OAuth URLs with configurable tenant
const MICROSOFT_AUTHORIZE_URL = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`;
const MICROSOFT_TOKEN_URL = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
// Client configuration from environment variables
const clientId = process.env.MICROSOFT_CLIENT_ID;
const clientSecret = process.env.MICROSOFT_CLIENT_SECRET;
const redirectUri = process.env.MICROSOFT_REDIRECT_URI;
// Log configuration for debugging
console.log('Microsoft OAuth Configuration:', {
tenantId,
authorizeUrl: MICROSOFT_AUTHORIZE_URL,
tokenUrl: MICROSOFT_TOKEN_URL,
clientIdFirstChars: clientId ? clientId.substring(0, 5) + '...' : 'undefined',
redirectUri
});
// Required scopes for IMAP and SMTP access
const REQUIRED_SCOPES = [
'offline_access',

View File

@ -0,0 +1,115 @@
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"email" TEXT NOT NULL,
"password" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Calendar" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"color" TEXT NOT NULL DEFAULT '#0082c9',
"description" TEXT,
"userId" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Calendar_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Event" (
"id" TEXT NOT NULL,
"title" TEXT NOT NULL,
"description" TEXT,
"start" TIMESTAMP(3) NOT NULL,
"end" TIMESTAMP(3) NOT NULL,
"location" TEXT,
"isAllDay" BOOLEAN NOT NULL DEFAULT false,
"calendarId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Event_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "MailCredentials" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"email" TEXT NOT NULL,
"password" TEXT,
"host" TEXT NOT NULL,
"port" INTEGER NOT NULL,
"secure" BOOLEAN NOT NULL DEFAULT true,
"useOAuth" BOOLEAN NOT NULL DEFAULT false,
"refreshToken" TEXT,
"accessToken" TEXT,
"tokenExpiry" TIMESTAMP(3),
"smtp_host" TEXT,
"smtp_port" INTEGER,
"smtp_secure" BOOLEAN DEFAULT false,
"display_name" TEXT,
"color" TEXT DEFAULT '#0082c9',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "MailCredentials_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "WebDAVCredentials" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"username" TEXT NOT NULL,
"password" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "WebDAVCredentials_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
-- CreateIndex
CREATE INDEX "Calendar_userId_idx" ON "Calendar"("userId");
-- CreateIndex
CREATE INDEX "Event_calendarId_idx" ON "Event"("calendarId");
-- CreateIndex
CREATE INDEX "Event_userId_idx" ON "Event"("userId");
-- CreateIndex
CREATE UNIQUE INDEX "MailCredentials_userId_email_key" ON "MailCredentials"("userId", "email");
-- CreateIndex
CREATE INDEX "MailCredentials_userId_idx" ON "MailCredentials"("userId");
-- CreateIndex
CREATE UNIQUE INDEX "WebDAVCredentials_userId_key" ON "WebDAVCredentials"("userId");
-- CreateIndex
CREATE INDEX "WebDAVCredentials_userId_idx" ON "WebDAVCredentials"("userId");
-- AddForeignKey
ALTER TABLE "Calendar" ADD CONSTRAINT "Calendar_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Event" ADD CONSTRAINT "Event_calendarId_fkey" FOREIGN KEY ("calendarId") REFERENCES "Calendar"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Event" ADD CONSTRAINT "Event_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "MailCredentials" ADD CONSTRAINT "MailCredentials_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "WebDAVCredentials" ADD CONSTRAINT "WebDAVCredentials_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"