mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2026-07-25 01:15:26 +10:00
update dependencies, fix type issues in auth, add migrations for missing indexes
This commit is contained in:
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
const nextPackages = ["@monaco-editor/react"];
|
||||
|
||||
const betaPackages = ["drizzle-orm", "drizzle-kit"];
|
||||
const betaPackages = ["drizzle-orm", "drizzle-kit", "drizzle-zod"];
|
||||
|
||||
/** @type {import('npm-check-updates').RunOptions} */
|
||||
module.exports = {
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE "user" ADD COLUMN "last_active_at" timestamp with time zone;--> statement-breakpoint
|
||||
ALTER TABLE "apikey" ALTER COLUMN "config_id" SET DEFAULT 'default';
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,6 @@
|
||||
ALTER TABLE "apikey" ALTER COLUMN "rate_limit_time_window" SET DEFAULT 86400000;--> statement-breakpoint
|
||||
ALTER TABLE "apikey" ALTER COLUMN "rate_limit_max" SET DEFAULT 10;--> statement-breakpoint
|
||||
ALTER TABLE "two_factor" ALTER COLUMN "secret" SET NOT NULL;--> statement-breakpoint
|
||||
ALTER TABLE "two_factor" ALTER COLUMN "backup_codes" SET NOT NULL;--> statement-breakpoint
|
||||
CREATE INDEX "apikey_config_id_index" ON "apikey" ("config_id");--> statement-breakpoint
|
||||
CREATE INDEX "verification_identifier_index" ON "verification" ("identifier");
|
||||
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -81,7 +81,7 @@
|
||||
"cmdk": "^1.1.1",
|
||||
"dompurify": "^3.3.3",
|
||||
"drizzle-orm": "1.0.0-beta.18-7eb39f0",
|
||||
"drizzle-zod": "^0.8.3",
|
||||
"drizzle-zod": "^1.0.0-beta.14-a36c63d",
|
||||
"es-toolkit": "^1.45.1",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-json-patch": "^3.1.1",
|
||||
|
||||
Generated
+6
-6
@@ -172,8 +172,8 @@ importers:
|
||||
specifier: 1.0.0-beta.18-7eb39f0
|
||||
version: 1.0.0-beta.18-7eb39f0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@types/mssql@9.1.9(@azure/core-client@1.10.1))(@types/pg@8.18.0)(mssql@11.0.1(@azure/core-client@1.10.1))(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(valibot@1.2.0(typescript@5.9.3))(zod@4.3.6)
|
||||
drizzle-zod:
|
||||
specifier: ^0.8.3
|
||||
version: 0.8.3(drizzle-orm@1.0.0-beta.18-7eb39f0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@types/mssql@9.1.9(@azure/core-client@1.10.1))(@types/pg@8.18.0)(mssql@11.0.1(@azure/core-client@1.10.1))(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(valibot@1.2.0(typescript@5.9.3))(zod@4.3.6))(zod@4.3.6)
|
||||
specifier: ^1.0.0-beta.14-a36c63d
|
||||
version: 1.0.0-beta.9-e89174b(drizzle-orm@1.0.0-beta.18-7eb39f0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@types/mssql@9.1.9(@azure/core-client@1.10.1))(@types/pg@8.18.0)(mssql@11.0.1(@azure/core-client@1.10.1))(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(valibot@1.2.0(typescript@5.9.3))(zod@4.3.6))(zod@4.3.6)
|
||||
es-toolkit:
|
||||
specifier: ^1.45.1
|
||||
version: 1.45.1
|
||||
@@ -4520,10 +4520,10 @@ packages:
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
drizzle-zod@0.8.3:
|
||||
resolution: {integrity: sha512-66yVOuvGhKJnTdiqj1/Xaaz9/qzOdRJADpDa68enqS6g3t0kpNkwNYjUuaeXgZfO/UWuIM9HIhSlJ6C5ZraMww==}
|
||||
drizzle-zod@1.0.0-beta.9-e89174b:
|
||||
resolution: {integrity: sha512-dnEHqeFk5KHuC5sqYEbXxk0FXcijiYRtLwI2/p/z4AclfyGBOcnCAakoVwbOdNHrF0emlc6ufyRl0NffVP1XRw==}
|
||||
peerDependencies:
|
||||
drizzle-orm: '>=0.36.0'
|
||||
drizzle-orm: '>=1.0.0-beta.2'
|
||||
zod: ^3.25.0 || ^4.0.0
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
@@ -12228,7 +12228,7 @@ snapshots:
|
||||
valibot: 1.2.0(typescript@5.9.3)
|
||||
zod: 4.3.6
|
||||
|
||||
drizzle-zod@0.8.3(drizzle-orm@1.0.0-beta.18-7eb39f0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@types/mssql@9.1.9(@azure/core-client@1.10.1))(@types/pg@8.18.0)(mssql@11.0.1(@azure/core-client@1.10.1))(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(valibot@1.2.0(typescript@5.9.3))(zod@4.3.6))(zod@4.3.6):
|
||||
drizzle-zod@1.0.0-beta.9-e89174b(drizzle-orm@1.0.0-beta.18-7eb39f0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@types/mssql@9.1.9(@azure/core-client@1.10.1))(@types/pg@8.18.0)(mssql@11.0.1(@azure/core-client@1.10.1))(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(valibot@1.2.0(typescript@5.9.3))(zod@4.3.6))(zod@4.3.6):
|
||||
dependencies:
|
||||
drizzle-orm: 1.0.0-beta.18-7eb39f0(@electric-sql/pglite@0.3.15)(@opentelemetry/api@1.9.0)(@types/mssql@9.1.9(@azure/core-client@1.10.1))(@types/pg@8.18.0)(mssql@11.0.1(@azure/core-client@1.10.1))(mysql2@3.15.3)(pg@8.20.0)(postgres@3.4.7)(valibot@1.2.0(typescript@5.9.3))(zod@4.3.6)
|
||||
zod: 4.3.6
|
||||
|
||||
@@ -64,7 +64,7 @@ export function UserDropdownMenu({ children }: Props) {
|
||||
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger render={children({ session })} />
|
||||
<DropdownMenuTrigger render={children({ session: session as AuthSession })} />
|
||||
|
||||
<DropdownMenuContent align="start" side="top">
|
||||
<DropdownMenuGroup>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { apiKeyClient } from "@better-auth/api-key/client";
|
||||
import { sentinelClient } from "@better-auth/infra/client";
|
||||
import { dashClient } from "@better-auth/infra/client";
|
||||
import { genericOAuthClient, inferAdditionalFields, twoFactorClient, usernameClient } from "better-auth/client/plugins";
|
||||
import { createAuthClient } from "better-auth/react";
|
||||
import type { auth } from "./config";
|
||||
@@ -7,8 +7,8 @@ import type { auth } from "./config";
|
||||
const getAuthClient = () => {
|
||||
return createAuthClient({
|
||||
plugins: [
|
||||
dashClient(),
|
||||
apiKeyClient(),
|
||||
sentinelClient(),
|
||||
usernameClient(),
|
||||
twoFactorClient({
|
||||
onTwoFactorRedirect() {
|
||||
|
||||
@@ -8,11 +8,11 @@ import { genericOAuth } from "better-auth/plugins/generic-oauth";
|
||||
import { twoFactor } from "better-auth/plugins/two-factor";
|
||||
import { username } from "better-auth/plugins/username";
|
||||
import { and, eq, or } from "drizzle-orm";
|
||||
import { db } from "@/integrations/drizzle/client";
|
||||
import { env } from "@/utils/env";
|
||||
import { hashPassword, verifyPassword } from "@/utils/password";
|
||||
import { generateId, toUsername } from "@/utils/string";
|
||||
import { schema } from "../drizzle";
|
||||
import { db } from "../drizzle/client";
|
||||
import { sendEmail } from "../email/service";
|
||||
|
||||
function isCustomOAuthProviderEnabled() {
|
||||
@@ -90,6 +90,7 @@ const getAuthConfig = () => {
|
||||
|
||||
telemetry: { enabled: false },
|
||||
trustedOrigins: getTrustedOrigins(),
|
||||
|
||||
advanced: {
|
||||
database: { generateId },
|
||||
useSecureCookies: env.APP_URL.startsWith("https://"),
|
||||
@@ -234,8 +235,8 @@ const getAuthConfig = () => {
|
||||
openAPI(),
|
||||
genericOAuth({ config: authConfigs }),
|
||||
twoFactor({ issuer: "Reactive Resume" }),
|
||||
dash({ apiKey: env.BETTER_AUTH_API_KEY }),
|
||||
apiKey({ enableSessionForAPIKeys: true, rateLimit: { enabled: false } }),
|
||||
dash({ apiKey: env.BETTER_AUTH_API_KEY, activityTracking: { enabled: true } }),
|
||||
username({
|
||||
minUsernameLength: 3,
|
||||
maxUsernameLength: 64,
|
||||
|
||||
@@ -8,7 +8,7 @@ export const getSession = createIsomorphicFn()
|
||||
.client(async (): Promise<AuthSession | null> => {
|
||||
const { data, error } = await authClient.getSession();
|
||||
if (error) return null;
|
||||
return data;
|
||||
return data as AuthSession;
|
||||
})
|
||||
.server(async (): Promise<AuthSession | null> => {
|
||||
const result = await auth.api.getSession({ headers: getRequestHeaders() });
|
||||
|
||||
@@ -3,9 +3,7 @@ import type { auth } from "./config";
|
||||
|
||||
export type AuthSession = {
|
||||
session: typeof auth.$Infer.Session.session;
|
||||
user: typeof auth.$Infer.Session.user & {
|
||||
name: string;
|
||||
};
|
||||
user: typeof auth.$Infer.Session.user;
|
||||
};
|
||||
|
||||
const authProviderSchema = z.enum(["credential", "google", "github", "custom"]);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { createServerOnlyFn } from "@tanstack/react-start";
|
||||
import { drizzle, type NodePgDatabase } from "drizzle-orm/node-postgres";
|
||||
import { Pool } from "pg";
|
||||
import { schema } from "@/integrations/drizzle";
|
||||
import { env } from "@/utils/env";
|
||||
import * as schema from "./schema";
|
||||
|
||||
// During hot reload (i.e., in development), global assignment ensures the pool/client persist across reloads.
|
||||
// This prevents exhausting connection limits due to re-creation on every reload.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { defineRelations } from "drizzle-orm";
|
||||
import * as pg from "drizzle-orm/pg-core";
|
||||
import { defaultResumeData, type ResumeData } from "../../schema/resume/data";
|
||||
import { generateId } from "../../utils/string";
|
||||
@@ -17,6 +18,7 @@ export const user = pg.pgTable(
|
||||
username: pg.text("username").notNull().unique(),
|
||||
displayUsername: pg.text("display_username").notNull().unique(),
|
||||
twoFactorEnabled: pg.boolean("two_factor_enabled").notNull().default(false),
|
||||
lastActiveAt: pg.timestamp("last_active_at", { withTimezone: true }),
|
||||
createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
updatedAt: pg
|
||||
.timestamp("updated_at", { withTimezone: true })
|
||||
@@ -84,22 +86,26 @@ export const account = pg.pgTable(
|
||||
(t) => [pg.index().on(t.userId)],
|
||||
);
|
||||
|
||||
export const verification = pg.pgTable("verification", {
|
||||
id: pg
|
||||
.uuid("id")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => generateId()),
|
||||
identifier: pg.text("identifier").notNull().unique(),
|
||||
value: pg.text("value").notNull(),
|
||||
expiresAt: pg.timestamp("expires_at", { withTimezone: true }).notNull(),
|
||||
createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
updatedAt: pg
|
||||
.timestamp("updated_at", { withTimezone: true })
|
||||
.notNull()
|
||||
.defaultNow()
|
||||
.$onUpdate(() => /* @__PURE__ */ new Date()),
|
||||
});
|
||||
export const verification = pg.pgTable(
|
||||
"verification",
|
||||
{
|
||||
id: pg
|
||||
.uuid("id")
|
||||
.notNull()
|
||||
.primaryKey()
|
||||
.$defaultFn(() => generateId()),
|
||||
identifier: pg.text("identifier").notNull().unique(),
|
||||
value: pg.text("value").notNull(),
|
||||
expiresAt: pg.timestamp("expires_at", { withTimezone: true }).notNull(),
|
||||
createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
updatedAt: pg
|
||||
.timestamp("updated_at", { withTimezone: true })
|
||||
.notNull()
|
||||
.defaultNow()
|
||||
.$onUpdate(() => /* @__PURE__ */ new Date()),
|
||||
},
|
||||
(t) => [pg.index().on(t.identifier)],
|
||||
);
|
||||
|
||||
export const twoFactor = pg.pgTable(
|
||||
"two_factor",
|
||||
@@ -113,8 +119,8 @@ export const twoFactor = pg.pgTable(
|
||||
.uuid("user_id")
|
||||
.notNull()
|
||||
.references(() => user.id, { onDelete: "cascade" }),
|
||||
secret: pg.text("secret"),
|
||||
backupCodes: pg.text("backup_codes"),
|
||||
secret: pg.text("secret").notNull(),
|
||||
backupCodes: pg.text("backup_codes").notNull(),
|
||||
createdAt: pg.timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
|
||||
updatedAt: pg
|
||||
.timestamp("updated_at", { withTimezone: true })
|
||||
@@ -239,8 +245,8 @@ export const apikey = pg.pgTable(
|
||||
lastRefillAt: pg.timestamp("last_refill_at", { withTimezone: true }),
|
||||
enabled: pg.boolean("enabled").notNull().default(true),
|
||||
rateLimitEnabled: pg.boolean("rate_limit_enabled").notNull().default(false),
|
||||
rateLimitTimeWindow: pg.integer("rate_limit_time_window"),
|
||||
rateLimitMax: pg.integer("rate_limit_max"),
|
||||
rateLimitTimeWindow: pg.integer("rate_limit_time_window").default(86400000),
|
||||
rateLimitMax: pg.integer("rate_limit_max").default(10),
|
||||
requestCount: pg.integer("request_count").notNull().default(0),
|
||||
remaining: pg.integer("remaining"),
|
||||
lastRequest: pg.timestamp("last_request", { withTimezone: true }),
|
||||
@@ -254,5 +260,70 @@ export const apikey = pg.pgTable(
|
||||
permissions: pg.text("permissions"),
|
||||
metadata: pg.jsonb("metadata"),
|
||||
},
|
||||
(t) => [pg.index().on(t.referenceId), pg.index().on(t.key), pg.index().on(t.enabled, t.referenceId)],
|
||||
(t) => [
|
||||
pg.index().on(t.referenceId),
|
||||
pg.index().on(t.key),
|
||||
pg.index().on(t.configId),
|
||||
pg.index().on(t.enabled, t.referenceId),
|
||||
],
|
||||
);
|
||||
|
||||
export const relations = defineRelations(
|
||||
{ user, session, account, verification, twoFactor, passkey, resume, resumeStatistics, apikey },
|
||||
(r) => ({
|
||||
user: {
|
||||
sessions: r.many.session(),
|
||||
accounts: r.many.account(),
|
||||
twoFactors: r.many.twoFactor(),
|
||||
passkeys: r.many.passkey(),
|
||||
resumes: r.many.resume(),
|
||||
apiKeys: r.many.apikey(),
|
||||
},
|
||||
session: {
|
||||
user: r.one.user({
|
||||
from: r.session.userId,
|
||||
to: r.user.id,
|
||||
}),
|
||||
},
|
||||
account: {
|
||||
user: r.one.user({
|
||||
from: r.account.userId,
|
||||
to: r.user.id,
|
||||
}),
|
||||
},
|
||||
twoFactor: {
|
||||
user: r.one.user({
|
||||
from: r.twoFactor.userId,
|
||||
to: r.user.id,
|
||||
}),
|
||||
},
|
||||
passkey: {
|
||||
user: r.one.user({
|
||||
from: r.passkey.userId,
|
||||
to: r.user.id,
|
||||
}),
|
||||
},
|
||||
resume: {
|
||||
user: r.one.user({
|
||||
from: r.resume.userId,
|
||||
to: r.user.id,
|
||||
}),
|
||||
statistics: r.one.resumeStatistics({
|
||||
from: r.resume.id,
|
||||
to: r.resumeStatistics.resumeId,
|
||||
}),
|
||||
},
|
||||
resumeStatistics: {
|
||||
resume: r.one.resume({
|
||||
from: r.resumeStatistics.resumeId,
|
||||
to: r.resume.id,
|
||||
}),
|
||||
},
|
||||
apikey: {
|
||||
user: r.one.user({
|
||||
from: r.apikey.referenceId,
|
||||
to: r.user.id,
|
||||
}),
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user