mirror of
https://github.com/fosrl/pangolin.git
synced 2025-06-29 08:30:05 +02:00
check for stale users on signup
This commit is contained in:
parent
3a52615e3e
commit
6fb569e2cd
4 changed files with 55 additions and 7 deletions
|
@ -39,6 +39,7 @@
|
|||
"http-errors": "2.0.0",
|
||||
"lucia": "3.2.0",
|
||||
"lucide-react": "0.447.0",
|
||||
"moment": "2.30.1",
|
||||
"next": "14.2.13",
|
||||
"node-fetch": "3.3.2",
|
||||
"nodemailer": "6.9.15",
|
||||
|
|
|
@ -5,7 +5,6 @@ import { Lucia, TimeSpan } from "lucia";
|
|||
import { DrizzleSQLiteAdapter } from "@lucia-auth/adapter-drizzle";
|
||||
import db from "@server/db";
|
||||
import { sessions, users } from "@server/db/schema";
|
||||
import environment from "@server/environment";
|
||||
|
||||
const adapter = new DrizzleSQLiteAdapter(db, sessions, users);
|
||||
|
||||
|
@ -16,6 +15,7 @@ export const lucia = new Lucia(adapter, {
|
|||
twoFactorEnabled: attributes.twoFactorEnabled,
|
||||
twoFactorSecret: attributes.twoFactorSecret,
|
||||
emailVerified: attributes.emailVerified,
|
||||
dateCreated: attributes.dateCreated,
|
||||
};
|
||||
},
|
||||
// getSessionAttributes: (attributes) => {
|
||||
|
@ -30,7 +30,7 @@ export const lucia = new Lucia(adapter, {
|
|||
// secure: environment.ENVIRONMENT === "prod",
|
||||
// sameSite: "strict",
|
||||
secure: false,
|
||||
domain: ".testing123.io"
|
||||
domain: ".testing123.io",
|
||||
},
|
||||
},
|
||||
sessionExpiresIn: new TimeSpan(2, "w"),
|
||||
|
@ -52,6 +52,7 @@ interface DatabaseUserAttributes {
|
|||
twoFactorEnabled: boolean;
|
||||
twoFactorSecret?: string;
|
||||
emailVerified: boolean;
|
||||
dateCreated: string;
|
||||
}
|
||||
|
||||
interface DatabaseSessionAttributes {
|
||||
|
|
|
@ -81,6 +81,7 @@ export const users = sqliteTable("user", {
|
|||
emailVerified: integer("emailVerified", { mode: "boolean" })
|
||||
.notNull()
|
||||
.default(false),
|
||||
dateCreated: text("dateCreated").notNull(),
|
||||
});
|
||||
|
||||
export const twoFactorBackupCodes = sqliteTable("twoFactorBackupCodes", {
|
||||
|
@ -107,7 +108,9 @@ export const userOrgs = sqliteTable("userOrgs", {
|
|||
orgId: integer("orgId")
|
||||
.notNull()
|
||||
.references(() => orgs.orgId),
|
||||
roleId: integer("roleId").notNull().references(() => roles.roleId),
|
||||
roleId: integer("roleId")
|
||||
.notNull()
|
||||
.references(() => roles.roleId),
|
||||
});
|
||||
|
||||
export const emailVerificationCodes = sqliteTable("emailVerificationCodes", {
|
||||
|
@ -137,7 +140,9 @@ export const actions = sqliteTable("actions", {
|
|||
|
||||
export const roles = sqliteTable("roles", {
|
||||
roleId: integer("roleId").primaryKey({ autoIncrement: true }),
|
||||
orgId: integer("orgId").references(() => orgs.orgId, { onDelete: "cascade" }),
|
||||
orgId: integer("orgId").references(() => orgs.orgId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
name: text("name").notNull(),
|
||||
description: text("description"),
|
||||
});
|
||||
|
@ -204,7 +209,9 @@ export const userResources = sqliteTable("userResources", {
|
|||
|
||||
export const limitsTable = sqliteTable("limits", {
|
||||
limitId: integer("limitId").primaryKey({ autoIncrement: true }),
|
||||
orgId: integer("orgId").references(() => orgs.orgId, { onDelete: "cascade" }),
|
||||
orgId: integer("orgId").references(() => orgs.orgId, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
name: text("name").notNull(),
|
||||
value: integer("value").notNull(),
|
||||
description: text("description"),
|
||||
|
|
|
@ -12,6 +12,8 @@ import response from "@server/utils/response";
|
|||
import { SqliteError } from "better-sqlite3";
|
||||
import { sendEmailVerificationCode } from "./sendEmailVerificationCode";
|
||||
import { passwordSchema } from "@server/auth/passwordSchema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import moment from "moment";
|
||||
|
||||
export const signupBodySchema = z.object({
|
||||
email: z.string().email(),
|
||||
|
@ -51,10 +53,47 @@ export async function signup(
|
|||
const userId = generateId(15);
|
||||
|
||||
try {
|
||||
const existing = await db
|
||||
.select()
|
||||
.from(users)
|
||||
.where(eq(users.email, email));
|
||||
|
||||
if (existing && existing.length > 0) {
|
||||
const user = existing[0];
|
||||
|
||||
// If the user is already verified, we don't want to create a new user
|
||||
if (user.emailVerified) {
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
"A user with that email address already exists",
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const dateCreated = moment(user.dateCreated);
|
||||
const now = moment();
|
||||
const diff = now.diff(dateCreated, "hours");
|
||||
|
||||
if (diff < 2) {
|
||||
// If the user was created less than 2 hours ago, we don't want to create a new user
|
||||
return next(
|
||||
createHttpError(
|
||||
HttpCode.BAD_REQUEST,
|
||||
"A verification email was already sent to this email address. Please check your email for the verification code.",
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// If the user was created more than 2 hours ago, we want to delete the old user and create a new one
|
||||
await db.delete(users).where(eq(users.id, user.id));
|
||||
}
|
||||
}
|
||||
|
||||
await db.insert(users).values({
|
||||
id: userId,
|
||||
email: email,
|
||||
passwordHash,
|
||||
dateCreated: moment().toISOString(),
|
||||
});
|
||||
|
||||
const session = await lucia.createSession(userId, {});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue