diff --git a/backend/app/api/v1/labelers.py b/backend/app/api/v1/labelers.py index c2a89181..e4613e81 100644 --- a/backend/app/api/v1/labelers.py +++ b/backend/app/api/v1/labelers.py @@ -38,8 +38,11 @@ def create_labeler( """ Create new labeler. """ + print("create_labelere") deps.api_auth(api_key, db, create=True) + print(item_in) item = crud.labeler.create(db=db, obj_in=item_in) + print(item) return item diff --git a/backend/scripts/run-local.sh b/backend/scripts/run-local.sh index 7c6efabc..6e89ddf0 100755 --- a/backend/scripts/run-local.sh +++ b/backend/scripts/run-local.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -export DATABASE_URI=postgresql://postgres:postgres@localhost:5432/postgres +export DATABASE_URI=postgresql://fozziethebeat@localhost:5432/ocgpt_backend uvicorn app.main:app --reload diff --git a/website/package-lock.json b/website/package-lock.json index 75f46ee5..58e33695 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -19,6 +19,7 @@ "eslint-config-next": "13.0.6", "next": "13.0.6", "next-auth": "^4.18.6", + "nodemailer": "^6.8.0", "react": "18.2.0", "react-dom": "18.2.0", "swr": "^2.0.0" @@ -2618,6 +2619,14 @@ "node-gyp-build-test": "build-test.js" } }, + "node_modules/nodemailer": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.8.0.tgz", + "integrity": "sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ==", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/oauth": { "version": "0.9.15", "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", @@ -5418,6 +5427,11 @@ "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz", "integrity": "sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==" }, + "nodemailer": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.8.0.tgz", + "integrity": "sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ==" + }, "oauth": { "version": "0.9.15", "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz", diff --git a/website/package.json b/website/package.json index 2afe3321..aa06bb05 100644 --- a/website/package.json +++ b/website/package.json @@ -21,6 +21,7 @@ "eslint-config-next": "13.0.6", "next": "13.0.6", "next-auth": "^4.18.6", + "nodemailer": "^6.8.0", "react": "18.2.0", "react-dom": "18.2.0", "swr": "^2.0.0" diff --git a/website/pages/api/auth/[...nextauth].js b/website/pages/api/auth/[...nextauth].js index 45fcd57e..06044ac1 100644 --- a/website/pages/api/auth/[...nextauth].js +++ b/website/pages/api/auth/[...nextauth].js @@ -1,23 +1,82 @@ import NextAuth from "next-auth"; import DiscordProvider from "next-auth/providers/discord"; +import EmailProvider from "next-auth/providers/email"; import { PrismaAdapter } from "@next-auth/prisma-adapter"; import prisma from "../../../lib/prismadb"; export const authOptions = { + // Ensure we can store user data in a database. adapter: PrismaAdapter(prisma), providers: [ + // Register a Discord auth method. DiscordProvider({ clientId: process.env.DISCORD_CLIENT_ID, clientSecret: process.env.DISCORD_CLIENT_SECRET, }), + // Register an email magic link auth method. + EmailProvider({ + server: { + host: process.env.EMAIL_SERVER_HOST, + port: process.env.EMAIL_SERVER_PORT, + auth: { + user: process.env.EMAIL_SERVER_USER, + pass: process.env.EMAIL_SERVER_PASSWORD, + }, + }, + from: process.env.EMAIL_FROM, + }), ], callbacks: { + /** + * Includes the raw user id in the session object. + */ async session({ session, token, user }) { - session.user.sub = token.sub; + session.user.id = user.id; return session; }, }, + events: { + /** + * When a new user signs in, we register them with the Labeler backend. + */ + async signIn({ user, account, profile, isNewUser }) { + if (!isNewUser) { + return; + } + try { + // Register the new user with the Labeler Backend. + const res = await fetch(`${process.env.FASTAPI_URL}/api/v1/labelers`, { + method: "POST", + headers: { + "X-API-Key": process.env.FASTAPI_KEY, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + discord_username: user.id, + display_name: user.name || user.email, + is_enabled: true, + notes: account.provider, + }), + }); + if (res.status !== 200) { + console.error(res.statusText); + return; + } + // Update the User entry with the Labeler Backend's ID so we can + // reference it later. + const { id: labelerId } = await res.json(); + await prisma.user.update({ + where: { id: user.id }, + data: { + labelerId, + }, + }); + } catch (error) { + console.error(error); + } + }, + }, }; export default NextAuth(authOptions); diff --git a/website/pages/api/prompts.js b/website/pages/api/prompts.js index 20e35f73..9d09641c 100644 --- a/website/pages/api/prompts.js +++ b/website/pages/api/prompts.js @@ -1,19 +1,28 @@ import { unstable_getServerSession } from "next-auth/next"; import { authOptions } from "./auth/[...nextauth]"; +/** + * Returns a list of prompts from the Labeler Backend. + */ export default async (req, res) => { const session = await unstable_getServerSession(req, res, authOptions); if (!session) { - res.status(200).json([{ name: "cat" }]); + res.status(401).end(); return; } - const promptRes = await fetch(`${process.env.FASTAPI_URL}/api/v1/prompts`, { - headers: { - "X-API-Key": process.env.FASTAPI_KEY, - }, - }); - const prompts = await promptRes.json(); + try { + const promptRes = await fetch(`${process.env.FASTAPI_URL}/api/v1/prompts`, { + headers: { + "X-API-Key": process.env.FASTAPI_KEY, + }, + }); + const prompts = await promptRes.json(); - res.status(200).json(prompts); + res.status(200).json(prompts); + } catch (error) { + console.error(error); + res.status(500); + } + res.end(); }; diff --git a/website/prisma/migrations/20221215101838_record_labeler_id/migration.sql b/website/prisma/migrations/20221215101838_record_labeler_id/migration.sql new file mode 100644 index 00000000..acbdbf8d --- /dev/null +++ b/website/prisma/migrations/20221215101838_record_labeler_id/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "User" ADD COLUMN "labelerId" INTEGER; diff --git a/website/prisma/schema.prisma b/website/prisma/schema.prisma index 9f2669f3..5ef3e0f0 100644 --- a/website/prisma/schema.prisma +++ b/website/prisma/schema.prisma @@ -5,7 +5,6 @@ datasource db { generator client { provider = "prisma-client-js" - previewFeatures = ["referentialActions"] } model Account { @@ -41,6 +40,10 @@ model User { email String? @unique emailVerified DateTime? image String? + + // Records the unique user id stored in the Labeler Backend. + labelerId Int? + accounts Account[] sessions Session[] }