source: server/authjs-handler.ts@ 1ebac59

main
Last change on this file since 1ebac59 was 66bf4fd, checked in by Tome <gjorgievtome@…>, 7 months ago

setup config

  • Property mode set to 100644
File size: 3.5 KB
Line 
1import { Auth, type AuthConfig, createActionURL, setEnvDefaults } from "@auth/core";
2import CredentialsProvider from "@auth/core/providers/credentials";
3import type { Session } from "@auth/core/types";
4import { enhance, type UniversalHandler, type UniversalMiddleware } from "@universal-middleware/core";
5import {eq} from "drizzle-orm";
6import { db } from "../database/drizzle/db";
7import { usersTable } from "../database/drizzle/schema";
8import bcrypt from "bcrypt";
9// import { users, accounts, sessions, verificationTokens } from "../database/drizzle/schema/auth";
10
11const authjsConfig = {
12 basePath: "/api/auth",
13 trustHost: true,
14 secret: process.env.AUTH_SECRET,
15 session: {
16 strategy: "jwt",
17 },
18 providers: [
19 CredentialsProvider({
20 name: "Credentials",
21 credentials: {
22 username: { label: "Username", type: "text" },
23 password: { label: "Password", type: "password" },
24 },
25 async authorize(credentials) {
26 const username = typeof credentials?.username === "string" ? credentials.username : null;
27 const password = typeof credentials?.password === "string" ? credentials.password : null;
28
29 if(!username || !password) { return null; }
30
31 const user = await db.query.usersTable.findFirst({
32 where: eq(usersTable.username, username),
33 });
34
35 if(!user) { return null; }
36
37 const isPasswordValid = await bcrypt.compare(password, user.passwordHash);
38
39 if(!isPasswordValid) { return null; }
40
41 return {
42 id: String(user.id),
43 name: user.username,
44 email: user.email,
45 }
46 },
47 }),
48 ],
49
50 callbacks: {
51 async jwt({ token, user }) {
52 if (user) token.sub = user.id;
53 return token;
54 },
55 async session({ session, token }) {
56 if (session.user && token.sub) session.user.id = token.sub;
57 return session;
58 },
59 },
60} satisfies Omit<AuthConfig, "raw">;
61
62/**
63 * Retrieve Auth.js session from Request
64 */
65export async function getSession(req: Request, config: Omit<AuthConfig, "raw">): Promise<Session | null> {
66 setEnvDefaults(process.env, config);
67 const requestURL = new URL(req.url);
68 const url = createActionURL("session", requestURL.protocol, req.headers, process.env, config);
69
70 const response = await Auth(new Request(url, { headers: { cookie: req.headers.get("cookie") ?? "" } }), config);
71
72 const { status = 200 } = response;
73
74 const data = await response.json();
75
76 if (!data || !Object.keys(data).length) return null;
77 if (status === 200) return data as Session;
78 throw new Error(typeof data === "object" && "message" in data ? (data.message as string) : undefined);
79}
80
81/**
82 * Add Auth.js session to context
83 * @link {@see https://authjs.dev/getting-started/session-management/get-session}
84 **/
85export const authjsSessionMiddleware: UniversalMiddleware = enhance(
86 async (request, context) => {
87 try {
88 return {
89 ...context,
90 session: await getSession(request, authjsConfig),
91 };
92 } catch (error) {
93 console.debug("authjsSessionMiddleware:", error);
94 return {
95 ...context,
96 session: null,
97 };
98 }
99 },
100 {
101 name: "pc-forge:authjs-middleware",
102 immutable: false,
103 },
104);
105
106/**
107 * Auth.js route
108 * @link {@see https://authjs.dev/getting-started/installation}
109 **/
110export const authjsHandler = enhance(
111 async (request) => {
112 return Auth(request, authjsConfig);
113 },
114 {
115 name: "pc-forge:authjs-handler",
116 path: "/api/auth/**",
117 method: ["GET", "POST"],
118 immutable: false,
119 },
120) satisfies UniversalHandler;
Note: See TracBrowser for help on using the repository browser.