-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #77 from diggerhq/feat/m2m-applications-support
add support for m2m applications for users
- Loading branch information
Showing
8 changed files
with
148 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains 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
This file contains 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 |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { withApiAuth } from '@/middleware/api'; | ||
import { NextResponse } from 'next/server'; | ||
|
||
export const GET = withApiAuth(async function ( | ||
req: Request, | ||
userEmail: string, | ||
) { | ||
// Your API logic here | ||
|
||
// user, default org, ... | ||
return NextResponse.json({ data: 'your project' }); | ||
}); |
This file contains 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 |
---|---|---|
@@ -0,0 +1,21 @@ | ||
'use server'; | ||
import { PrismaClient } from '@prisma/client'; | ||
|
||
export async function getM2MApplication(clientId: string) { | ||
const prisma = new PrismaClient(); | ||
|
||
try { | ||
const m2mApp = await prisma.user_m2m_applications.findFirst({ | ||
where: { clientId: clientId || '' }, | ||
}); | ||
|
||
if (!m2mApp) { | ||
console.log('No matching M2M application found for client ID:', clientId); | ||
throw new Error('m2m2 application not found'); | ||
} | ||
|
||
return m2mApp; | ||
} finally { | ||
await prisma.$disconnect(); | ||
} | ||
} |
This file contains 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 |
---|---|---|
@@ -0,0 +1,43 @@ | ||
// middleware/withApiAuth.ts | ||
|
||
import { auth } from '@/auth'; | ||
import { headers } from 'next/headers'; | ||
import { NextRequest, NextResponse } from 'next/server'; | ||
import { validateM2MToken } from './m2m'; | ||
|
||
export function withApiAuth( | ||
handler: (req: NextRequest, userEmail: string) => Promise<NextResponse>, | ||
) { | ||
return async function (req: NextRequest) { | ||
// Check for M2M Bearer token | ||
try { | ||
const headersList = headers(); | ||
const authHeader = headersList.get('authorization'); | ||
|
||
if (authHeader?.startsWith('Bearer ')) { | ||
const token = authHeader.split(' ')[1]; | ||
const payload = await validateM2MToken(token); | ||
if (payload) { | ||
// Valid M2M token | ||
return handler(req, payload.email); | ||
} | ||
} | ||
|
||
// this part is to check if there is a cookie session available | ||
// example if request is made from browser api | ||
const session = await auth(); | ||
if (!session) { | ||
return new NextResponse('Unauthorized', { status: 401 }); | ||
} | ||
|
||
if (!session?.user?.email) { | ||
throw new Error('could not retrieve email from session'); | ||
} | ||
|
||
return handler(req, session.user?.email); | ||
} catch (error) { | ||
console.error('Auth error:', error); | ||
return new NextResponse('Internal Server Error', { status: 500 }); | ||
} | ||
}; | ||
} |
This file contains 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 |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import { getM2MApplication } from '@/data/user/m2m'; | ||
import { createRemoteJWKSet, decodeJwt, jwtVerify } from 'jose'; | ||
export async function validateM2MToken(token: string) { | ||
try { | ||
// Decode without verification to get clientId | ||
const decoded = decodeJwt(token); | ||
const clientId = String(decoded.azp) || String(decoded.client_id); | ||
|
||
// Only verify if this clientId is registered in our system | ||
const m2mApp = await getM2MApplication(clientId); | ||
console.log('verifying app for:', m2mApp.email); | ||
|
||
// Verify the token | ||
const auth0Domain = m2mApp.issuer; | ||
const audience = m2mApp.audience; | ||
|
||
const jwks = createRemoteJWKSet( | ||
new URL(`${auth0Domain}/.well-known/jwks.json`), | ||
); | ||
|
||
// TODO: figure out the correct typing here | ||
// @ts-ignore | ||
const { payload } = await jwtVerify(token, jwks, { | ||
audience: [audience], | ||
issuer: `${auth0Domain}/`, | ||
algorithms: ['RS256'], | ||
}); | ||
|
||
return { | ||
payload, | ||
email: m2mApp.email, | ||
m2mApp, | ||
}; | ||
} catch (error) { | ||
console.error('Token validation error:', error); | ||
return null; | ||
} | ||
} |
This file contains 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 |
---|---|---|
@@ -0,0 +1,16 @@ | ||
CREATE TABLE "user_m2m_applications" ( | ||
"id" SERIAL PRIMARY KEY, | ||
"email" TEXT NOT NULL, | ||
"clientId" TEXT UNIQUE NOT NULL, | ||
"audience" TEXT NOT NULL, | ||
"issuer" TEXT NOT NULL, | ||
"name" TEXT, | ||
"description" TEXT, | ||
"created_at" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP, | ||
"updated_at" TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP | ||
); | ||
|
||
-- Create an index on userId for better query performance | ||
CREATE INDEX "m2m_application_user_id_idx" ON "user_m2m_applications"("email"); | ||
|
||
|