Convert remaining routes to Drizzle

This commit is contained in:
Jesse Wierzbinski 2024-04-13 14:07:05 -10:00
parent 05e45ff5aa
commit 90d522eaa3
No known key found for this signature in database
14 changed files with 383 additions and 422 deletions

View file

@ -6,7 +6,8 @@ import {
generateRandomCodeVerifier,
processDiscoveryResponse,
} from "oauth4webapi";
import { client } from "~database/datasource";
import { db } from "~drizzle/db";
import { openIdLoginFlow } from "~drizzle/schema";
export const meta = applyConfig({
allowedMethods: ["GET"],
@ -60,20 +61,26 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
const codeVerifier = generateRandomCodeVerifier();
// Store into database
const newFlow = await client.openIdLoginFlow.create({
data: {
codeVerifier,
application: {
connect: {
client_id: clientId,
},
},
issuerId,
},
const application = await db.query.application.findFirst({
where: (application, { eq }) => eq(application.clientId, clientId),
});
if (!application) {
return redirectToLogin("Invalid client_id");
}
// Store into database
const newFlow = (
await db
.insert(openIdLoginFlow)
.values({
codeVerifier,
applicationId: application.id,
issuerId,
})
.returning()
)[0];
const codeChallenge = await calculatePKCECodeChallenge(codeVerifier);
return Response.redirect(

View file

@ -13,8 +13,10 @@ import {
userInfoRequest,
validateAuthResponse,
} from "oauth4webapi";
import { client } from "~database/datasource";
import { TokenType } from "~database/entities/Token";
import { db } from "~drizzle/db";
import { token } from "~drizzle/schema";
import { findFirstUser } from "~database/entities/User";
export const meta = applyConfig({
allowedMethods: ["GET"],
@ -46,11 +48,10 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
// Remove state query parameter from URL
currentUrl.searchParams.delete("state");
const issuerParam = matchedRoute.params.issuer;
const flow = await client.openIdLoginFlow.findFirst({
where: {
id: matchedRoute.query.flow,
},
include: {
const flow = await db.query.openIdLoginFlow.findFirst({
where: (flow, { eq }) => eq(flow.id, matchedRoute.query.flow),
with: {
application: true,
},
});
@ -142,15 +143,19 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
),
);
const user = await client.user.findFirst({
where: {
linkedOpenIdAccounts: {
some: {
serverId: sub,
issuerId: issuer.id,
},
},
},
const userId = (
await db.query.openIdAccount.findFirst({
where: (account, { eq, and }) =>
and(eq(account.serverId, sub), eq(account.issuerId, issuer.id)),
})
)?.userId;
if (!userId) {
return redirectToLogin("No user found with that account");
}
const user = await findFirstUser({
where: (user, { eq }) => eq(user.id, userId),
});
if (!user) {
@ -161,31 +166,21 @@ export default apiRoute(async (req, matchedRoute, extraData) => {
const code = randomBytes(32).toString("hex");
await client.application.update({
where: { id: flow.application.id },
data: {
tokens: {
create: {
access_token: randomBytes(64).toString("base64url"),
code: code,
scope: flow.application.scopes,
token_type: TokenType.BEARER,
user: {
connect: {
id: user.id,
},
},
},
},
},
await db.insert(token).values({
accessToken: randomBytes(64).toString("base64url"),
code: code,
scope: flow.application.scopes,
tokenType: TokenType.BEARER,
userId: user.id,
applicationId: flow.application.id,
});
// Redirect back to application
return Response.redirect(
`/oauth/redirect?${new URLSearchParams({
redirect_uri: flow.application.redirect_uris,
redirect_uri: flow.application.redirectUris,
code,
client_id: flow.application.client_id,
client_id: flow.application.clientId,
application: flow.application.name,
website: flow.application.website ?? "",
scope: flow.application.scopes,

View file

@ -1,6 +1,6 @@
import { apiRoute, applyConfig } from "@api";
import { errorResponse, jsonResponse } from "@response";
import { client } from "~database/datasource";
import { db } from "~drizzle/db";
export const meta = applyConfig({
allowedMethods: ["POST"],
@ -34,30 +34,41 @@ export default apiRoute<{
400,
);
if (!code || !redirect_uri || !client_id || !client_secret || !scope)
return errorResponse(
"Missing required parameters code, redirect_uri, client_id, client_secret, scope",
400,
);
// Get associated token
const token = await client.token.findFirst({
where: {
code,
application: {
client_id,
secret: client_secret,
redirect_uris: redirect_uri,
scopes: scope?.replaceAll("+", " "),
},
scope: scope?.replaceAll("+", " "),
},
include: {
application: true,
},
const application = await db.query.application.findFirst({
where: (application, { eq, and }) =>
and(
eq(application.clientId, client_id),
eq(application.secret, client_secret),
eq(application.redirectUris, redirect_uri),
eq(application.scopes, scope?.replaceAll("+", " ")),
),
});
if (!application)
return errorResponse(
"Invalid client credentials (missing applicaiton)",
401,
);
const token = await db.query.token.findFirst({
where: (token, { eq }) =>
eq(token.code, code) && eq(token.applicationId, application.id),
});
if (!token)
return errorResponse("Invalid access token or client credentials", 401);
return jsonResponse({
access_token: token.access_token,
token_type: token.token_type,
access_token: token.accessToken,
token_type: token.tokenType,
scope: token.scope,
created_at: Number(token.created_at),
created_at: new Date(token.createdAt).getTime(),
});
});