-
Notifications
You must be signed in to change notification settings - Fork 89
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create users & auth endpoints in backend (#85)
- Loading branch information
Showing
248 changed files
with
8,006 additions
and
1,423 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,8 @@ ui-debug.log | |
.husky | ||
tmp | ||
|
||
vitest.config.ts.timestamp-* | ||
|
||
# Dependencies | ||
node_modules | ||
|
||
|
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
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
22 changes: 22 additions & 0 deletions
22
apps/backend/prisma/migrations/20240702050143_verification_codes/migration.sql
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,22 @@ | ||
-- CreateEnum | ||
CREATE TYPE "VerificationCodeType" AS ENUM ('ONE_TIME_PASSWORD'); | ||
|
||
-- CreateTable | ||
CREATE TABLE "VerificationCode" ( | ||
"projectId" TEXT NOT NULL, | ||
"id" UUID NOT NULL, | ||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
"updatedAt" TIMESTAMP(3) NOT NULL, | ||
"type" "VerificationCodeType" NOT NULL, | ||
"code" TEXT NOT NULL, | ||
"expiresAt" TIMESTAMP(3) NOT NULL, | ||
"usedAt" TIMESTAMP(3), | ||
"redirectUrl" TEXT, | ||
"email" TEXT NOT NULL, | ||
"data" JSONB NOT NULL, | ||
|
||
CONSTRAINT "VerificationCode_pkey" PRIMARY KEY ("projectId","id") | ||
); | ||
|
||
-- CreateIndex | ||
CREATE UNIQUE INDEX "VerificationCode_projectId_code_key" ON "VerificationCode"("projectId", "code"); |
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
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
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
3 changes: 3 additions & 0 deletions
3
apps/backend/src/app/api/v1/auth/oauth/access-token/[provider]/route.tsx
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,3 @@ | ||
import { NextResponse } from "next/server"; | ||
|
||
export const GET = () => NextResponse.json("TODO"); |
3 changes: 3 additions & 0 deletions
3
apps/backend/src/app/api/v1/auth/oauth/authorize/[provider]/route.tsx
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,3 @@ | ||
import { NextResponse } from "next/server"; | ||
|
||
export const GET = () => NextResponse.json("TODO"); |
3 changes: 3 additions & 0 deletions
3
apps/backend/src/app/api/v1/auth/oauth/callback/[provider]/route.tsx
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,3 @@ | ||
import { NextResponse } from "next/server"; | ||
|
||
export const GET = () => NextResponse.json("TODO"); |
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,3 @@ | ||
import { NextResponse } from "next/server"; | ||
|
||
export const GET = () => NextResponse.json("TODO"); |
88 changes: 88 additions & 0 deletions
88
apps/backend/src/app/api/v1/auth/otp/send-sign-in-code/route.tsx
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,88 @@ | ||
import * as yup from "yup"; | ||
import { prismaClient } from "@/prisma-client"; | ||
import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler"; | ||
import { sendEmailFromTemplate } from "@/lib/emails"; | ||
import { StackAssertionError, StatusError } from "@stackframe/stack-shared/dist/utils/errors"; | ||
import { signInVerificationCodeHandler } from "../sign-in/verification-code-handler"; | ||
import { adaptSchema, clientOrHigherAuthTypeSchema, signInEmailSchema, verificationLinkRedirectUrlSchema } from "@stackframe/stack-shared/dist/schema-fields"; | ||
import { usersCrudHandlers } from "../../../users/crud"; | ||
|
||
export const POST = createSmartRouteHandler({ | ||
request: yup.object({ | ||
auth: yup.object({ | ||
type: clientOrHigherAuthTypeSchema, | ||
project: adaptSchema, | ||
}).required(), | ||
body: yup.object({ | ||
email: signInEmailSchema.required(), | ||
redirectUrl: verificationLinkRedirectUrlSchema, | ||
}).required(), | ||
}), | ||
response: yup.object({ | ||
statusCode: yup.number().oneOf([200]).required(), | ||
bodyType: yup.string().oneOf(["success"]).required(), | ||
}), | ||
async handler({ auth: { project }, body: { email, redirectUrl } }, fullReq) { | ||
if (!project.evaluatedConfig.magicLinkEnabled) { | ||
throw new StatusError(StatusError.Forbidden, "Magic link is not enabled for this project"); | ||
} | ||
|
||
const usersPrisma = await prismaClient.projectUser.findMany({ | ||
where: { | ||
projectId: project.id, | ||
primaryEmail: email, | ||
authWithEmail: true, | ||
}, | ||
}); | ||
if (usersPrisma.length > 1) { | ||
throw new StackAssertionError(`Multiple users found in the database with the same primary email ${email}, and all with e-mail sign-in allowed. This should never happen (only non-email/OAuth accounts are allowed to share the same primaryEmail).`); | ||
} | ||
|
||
const userPrisma = usersPrisma.length > 0 ? usersPrisma[0] : null; | ||
const isNewUser = !userPrisma; | ||
let userObj: Pick<NonNullable<typeof userPrisma>, "projectUserId" | "displayName" | "primaryEmail"> | null = userPrisma; | ||
if (!userObj) { | ||
// TODO this should be in the same transaction as the read above | ||
const createdUser = await usersCrudHandlers.adminCreate({ | ||
project, | ||
data: { | ||
auth_with_email: true, | ||
primary_email: email, | ||
primary_email_verified: false, | ||
}, | ||
}); | ||
userObj = { | ||
projectUserId: createdUser.id, | ||
displayName: createdUser.display_name, | ||
primaryEmail: createdUser.primary_email, | ||
}; | ||
} | ||
|
||
const { link } = await signInVerificationCodeHandler.sendCode({ | ||
project, | ||
method: { email }, | ||
data: { | ||
user_id: userObj.projectUserId, | ||
is_new_user: isNewUser, | ||
}, | ||
redirectUrl, | ||
}); | ||
|
||
await sendEmailFromTemplate({ | ||
project, | ||
email, | ||
templateId: "MAGIC_LINK", | ||
variables: { | ||
userDisplayName: userObj.displayName, | ||
userPrimaryEmail: userObj.primaryEmail, | ||
projectDisplayName: project.displayName, | ||
magicLink: link.toString(), | ||
}, | ||
}); | ||
|
||
return { | ||
statusCode: 200, | ||
bodyType: "success", | ||
}; | ||
}, | ||
}); |
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,3 @@ | ||
import { signInVerificationCodeHandler } from "./verification-code-handler"; | ||
|
||
export const POST = signInVerificationCodeHandler.postHandler; |
47 changes: 47 additions & 0 deletions
47
apps/backend/src/app/api/v1/auth/otp/sign-in/verification-code-handler.tsx
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,47 @@ | ||
import * as yup from "yup"; | ||
import { prismaClient } from "@/prisma-client"; | ||
import { createAuthTokens } from "@/lib/tokens"; | ||
import { createVerificationCodeHandler } from "@/route-handlers/verification-code-handler"; | ||
import { signInResponseSchema } from "@stackframe/stack-shared/dist/schema-fields"; | ||
import { VerificationCodeType } from "@prisma/client"; | ||
|
||
export const signInVerificationCodeHandler = createVerificationCodeHandler({ | ||
type: VerificationCodeType.ONE_TIME_PASSWORD, | ||
data: yup.object({ | ||
user_id: yup.string().required(), | ||
is_new_user: yup.boolean().required(), | ||
}), | ||
response: yup.object({ | ||
statusCode: yup.number().oneOf([200]).required(), | ||
body: signInResponseSchema.required(), | ||
}), | ||
async handler(project, { email }, data) { | ||
const projectUser = await prismaClient.projectUser.update({ | ||
where: { | ||
projectId_projectUserId: { | ||
projectId: project.id, | ||
projectUserId: data.user_id, | ||
}, | ||
primaryEmail: email, | ||
}, | ||
data: { | ||
primaryEmailVerified: true, | ||
}, | ||
}); | ||
|
||
const { refreshToken, accessToken } = await createAuthTokens({ | ||
projectId: project.id, | ||
projectUserId: projectUser.projectUserId, | ||
}); | ||
|
||
return { | ||
statusCode: 200, | ||
body: { | ||
refresh_token: refreshToken, | ||
access_token: accessToken, | ||
is_new_user: data.is_new_user, | ||
user_id: data.user_id, | ||
}, | ||
}; | ||
}, | ||
}); |
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,3 @@ | ||
import { NextResponse } from "next/server"; | ||
|
||
export const GET = () => NextResponse.json("TODO"); |
3 changes: 3 additions & 0 deletions
3
apps/backend/src/app/api/v1/auth/password/send-reset-code/route.tsx
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,3 @@ | ||
import { NextResponse } from "next/server"; | ||
|
||
export const GET = () => NextResponse.json("TODO"); |
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,3 @@ | ||
import { NextResponse } from "next/server"; | ||
|
||
export const GET = () => NextResponse.json("TODO"); |
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,3 @@ | ||
import { NextResponse } from "next/server"; | ||
|
||
export const GET = () => NextResponse.json("TODO"); |
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,3 @@ | ||
import { NextResponse } from "next/server"; | ||
|
||
export const GET = () => NextResponse.json("TODO"); |
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,3 @@ | ||
import { NextResponse } from "next/server"; | ||
|
||
export const GET = () => NextResponse.json("TODO"); |
Oops, something went wrong.