151 lines
3.5 KiB
TypeScript
151 lines
3.5 KiB
TypeScript
import { db } from "@/db/db";
|
|
import { authRequestsTable } from "@/db/schema";
|
|
import type { App } from "@/routes/app";
|
|
import { authError } from "@/routes/authError";
|
|
import { z, createRoute } from "@hono/zod-openapi";
|
|
import { eq } from "drizzle-orm";
|
|
import jwt from "jsonwebtoken";
|
|
import crypto from "crypto";
|
|
import { getOrgOrUserDisplayName } from "@/server/getOrgOrUserDisplayName";
|
|
import ms from "ms";
|
|
|
|
const route = createRoute({
|
|
method: "get",
|
|
path: "/auth-response/:request_id",
|
|
tags: ["comfyui"],
|
|
summary: "Get an API Key with code",
|
|
description:
|
|
"This endpoints is specifically built for ComfyUI workflow upload.",
|
|
request: {
|
|
params: z.object({
|
|
request_id: z.string(),
|
|
}),
|
|
},
|
|
responses: {
|
|
200: {
|
|
content: {
|
|
"application/json": {
|
|
schema: z.object({
|
|
api_key: z.string(),
|
|
name: z.string(),
|
|
}),
|
|
},
|
|
},
|
|
description: "The returned API Key",
|
|
},
|
|
201: {
|
|
content: {
|
|
"application/json": {
|
|
schema: z.object({
|
|
message: z.string(),
|
|
}),
|
|
},
|
|
},
|
|
description: "The API key is not yet ready",
|
|
},
|
|
500: {
|
|
content: {
|
|
"application/json": {
|
|
schema: z.object({
|
|
error: z.string(),
|
|
}),
|
|
},
|
|
},
|
|
description: "Error when fetching the API Key with code",
|
|
},
|
|
...authError,
|
|
},
|
|
});
|
|
|
|
const corsHeaders = {
|
|
"Access-Control-Allow-Origin": "*",
|
|
"Access-Control-Allow-Methods": "GET, OPTIONS",
|
|
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
};
|
|
|
|
export const registerGetAuthResponse = (app: App) => {
|
|
return app.openapi(route, async (c) => {
|
|
const { request_id } = c.req.valid("param");
|
|
|
|
try {
|
|
const result = await db.query.authRequestsTable.findFirst({
|
|
where: eq(authRequestsTable.request_id, request_id),
|
|
});
|
|
|
|
if (result?.api_hash) {
|
|
return c.json(
|
|
{
|
|
message: "Already used.",
|
|
},
|
|
{
|
|
status: 201,
|
|
headers: corsHeaders,
|
|
},
|
|
);
|
|
}
|
|
|
|
if (result && result.user_id) {
|
|
const expireTime = "1w";
|
|
const token = jwt.sign(
|
|
{ user_id: result.user_id, org_id: result.org_id },
|
|
process.env.JWT_SECRET!,
|
|
{
|
|
expiresIn: expireTime,
|
|
},
|
|
);
|
|
|
|
const hash = crypto.createHash("sha256").update(token).digest("hex");
|
|
|
|
const now = new Date();
|
|
const expiryDate = new Date(now.getTime() + ms(expireTime));
|
|
|
|
await db
|
|
.update(authRequestsTable)
|
|
.set({
|
|
api_hash: hash,
|
|
expired_date: expiryDate,
|
|
})
|
|
.where(eq(authRequestsTable.request_id, request_id));
|
|
|
|
const userName = await getOrgOrUserDisplayName(
|
|
result.org_id,
|
|
result.user_id,
|
|
);
|
|
|
|
return c.json(
|
|
{
|
|
api_key: token,
|
|
name: userName,
|
|
},
|
|
{
|
|
status: 200,
|
|
headers: corsHeaders,
|
|
},
|
|
);
|
|
}
|
|
} catch (error: unknown) {
|
|
const errorMessage =
|
|
error instanceof Error ? error.message : "Unknown error";
|
|
return c.json(
|
|
{
|
|
error: errorMessage,
|
|
},
|
|
{
|
|
statusText: "Invalid request",
|
|
status: 500,
|
|
headers: corsHeaders,
|
|
},
|
|
);
|
|
}
|
|
return c.json(
|
|
{
|
|
message: "Not ready yet.",
|
|
},
|
|
{
|
|
status: 201,
|
|
headers: corsHeaders,
|
|
},
|
|
);
|
|
});
|
|
};
|