fix: read cloudflare-style envs

master
Avraham Sakal 2 weeks ago
parent 3ae805220a
commit d9053e1fc0

@ -8,14 +8,13 @@ import {
import GoogleProvider from "@auth/core/providers/google"; import GoogleProvider from "@auth/core/providers/google";
import type { Session } from "@auth/core/types"; import type { Session } from "@auth/core/types";
// TODO: stop using universal-middleware and directly integrate server middlewares instead and/or use vike-server https://vike.dev/server. (Bati generates boilerplates that use universal-middleware https://github.com/magne4000/universal-middleware to make Bati's internal logic easier. This is temporary and will be removed soon.) // TODO: stop using universal-middleware and directly integrate server middlewares instead and/or use vike-server https://vike.dev/server. (Bati generates boilerplates that use universal-middleware https://github.com/magne4000/universal-middleware to make Bati's internal logic easier. This is temporary and will be removed soon.)
import type { import {
Get, type Get,
UniversalHandler, type UniversalHandler,
UniversalMiddleware, type UniversalMiddleware,
env as getEnv,
} from "@universal-middleware/core"; } from "@universal-middleware/core";
import { env } from "./env.js";
import { getDbClient } from "../database/index.js"; import { getDbClient } from "../database/index.js";
import { JWT } from "@auth/core/jwt";
if (!globalThis.crypto) { if (!globalThis.crypto) {
/** /**
@ -30,113 +29,114 @@ if (!globalThis.crypto) {
}); });
} }
const authjsConfig = { const authjsConfig = (env: Record<string, string>) =>
basePath: "/api/auth", ({
// trustHost: Boolean( basePath: "/api/auth",
// env.AUTH_TRUST_HOST ?? env.VERCEL ?? env.NODE_ENV !== "production" // trustHost: Boolean(
// ), // env.AUTH_TRUST_HOST ?? env.VERCEL ?? env.NODE_ENV !== "production"
trustHost: true, // ),
// TODO: Replace secret {@see https://authjs.dev/reference/core#secret} trustHost: true,
secret: env.AUTHJS_SECRET, // TODO: Replace secret {@see https://authjs.dev/reference/core#secret}
providers: [ secret: env.AUTHJS_SECRET,
// TODO: Choose and implement providers providers: [
// CredentialsProvider({ // TODO: Choose and implement providers
// name: "Credentials", // CredentialsProvider({
// credentials: { // name: "Credentials",
// username: { label: "Username", type: "text", placeholder: "jsmith" }, // credentials: {
// password: { label: "Password", type: "password" }, // username: { label: "Username", type: "text", placeholder: "jsmith" },
// }, // password: { label: "Password", type: "password" },
// async authorize() { // },
// // Add logic here to look up the user from the credentials supplied // async authorize() {
// const user = { // // Add logic here to look up the user from the credentials supplied
// id: "019900bb-61b3-7333-b760-b27784dfe33b", // const user = {
// name: "J Smith", // id: "019900bb-61b3-7333-b760-b27784dfe33b",
// email: "jsmith@example.com", // name: "J Smith",
// }; // email: "jsmith@example.com",
// };
// // Any object returned will be saved in `user` property of the JWT // // Any object returned will be saved in `user` property of the JWT
// // If you return null then an error will be displayed advising the user to check their details. // // If you return null then an error will be displayed advising the user to check their details.
// // You can also Reject this callback with an Error thus the user will be sent to the error page with the error message as a query parameter // // You can also Reject this callback with an Error thus the user will be sent to the error page with the error message as a query parameter
// return user ?? null; // return user ?? null;
// }, // },
// }), // }),
GoogleProvider({ GoogleProvider({
clientId: env.GOOGLE_CLIENT_ID, clientId: env.GOOGLE_CLIENT_ID,
clientSecret: env.GOOGLE_CLIENT_SECRET, clientSecret: env.GOOGLE_CLIENT_SECRET,
}), }),
], ],
callbacks: { callbacks: {
async signIn({ user, account, profile }) { async signIn({ user, account, profile }) {
if (typeof user?.email !== "string") return false; if (typeof user?.email !== "string") return false;
//@ts-ignore //@ts-ignore
const dbClient = await getDbClient(env.POSTGRES_CONNECTION_STRING); const dbClient = await getDbClient(env.POSTGRES_CONNECTION_STRING);
let userFromDb = await dbClient let userFromDb = await dbClient
.selectFrom("users") .selectFrom("users")
.selectAll() .selectAll()
.where("email", "=", user.email) .where("email", "=", user.email)
.executeTakeFirst(); .executeTakeFirst();
if (!userFromDb) { if (!userFromDb) {
userFromDb = ( userFromDb = (
await dbClient await dbClient
.insertInto("users") .insertInto("users")
.values({ .values({
email: user.email, email: user.email,
username: user.email, username: user.email,
password: null, password: null,
createdAt: null, createdAt: null,
lastLogin: null, lastLogin: null,
}) })
.returningAll() .returningAll()
.execute() .execute()
)[0]; )[0];
} }
console.log("signIn", user, account, profile); console.log("signIn", user, account, profile);
return true; return true;
}, },
jwt: async ({ token }) => { jwt: async ({ token }) => {
if (typeof token?.email !== "string") return token; if (typeof token?.email !== "string") return token;
//@ts-ignore //@ts-ignore
const dbClient = await getDbClient(env.POSTGRES_CONNECTION_STRING); const dbClient = await getDbClient(env.POSTGRES_CONNECTION_STRING);
let userFromDb = await dbClient let userFromDb = await dbClient
.selectFrom("users") .selectFrom("users")
.selectAll() .selectAll()
.where("email", "=", token.email || "") .where("email", "=", token.email || "")
.executeTakeFirst(); .executeTakeFirst();
/** TODO: the following should never happen, because the account in /** TODO: the following should never happen, because the account in
* created in the `isgnIn` step; but I don't know what error to throw here * created in the `isgnIn` step; but I don't know what error to throw here
* if for some reason there is no such account.*/ * if for some reason there is no such account.*/
if (!userFromDb) { if (!userFromDb) {
userFromDb = ( userFromDb = (
await dbClient await dbClient
.insertInto("users") .insertInto("users")
.values({ .values({
email: token.email, email: token.email,
username: token.email, username: token.email,
password: null, password: null,
createdAt: null, createdAt: null,
lastLogin: null, lastLogin: null,
}) })
.returningAll() .returningAll()
.execute() .execute()
)[0]; )[0];
} }
return { return {
...token, ...token,
id: userFromDb?.id || "", id: userFromDb?.id || "",
}; };
}, },
session: ({ token, session }) => { session: ({ token, session }) => {
return { return {
...session, ...session,
user: { user: {
...session.user, ...session.user,
id: token.id as string, id: token.id as string,
}, },
jwt: token, jwt: token,
}; };
},
}, },
}, } satisfies Omit<AuthConfig, "raw">);
} satisfies Omit<AuthConfig, "raw">;
/** /**
* Retrieve Auth.js session from Request * Retrieve Auth.js session from Request
@ -174,11 +174,15 @@ export async function getSession(
* @link {@see https://authjs.dev/getting-started/session-management/get-session} * @link {@see https://authjs.dev/getting-started/session-management/get-session}
**/ **/
export const authjsSessionMiddleware: Get<[], UniversalMiddleware> = export const authjsSessionMiddleware: Get<[], UniversalMiddleware> =
() => async (request, context) => { () => async (request, context, runtime) => {
const env = getEnv(runtime);
try { try {
return { return {
...context, ...context,
session: await getSession(request, authjsConfig), session: await getSession(
request,
authjsConfig(env as Record<string, string>)
),
}; };
} catch (error) { } catch (error) {
console.debug("authjsSessionMiddleware:", error); console.debug("authjsSessionMiddleware:", error);
@ -193,6 +197,7 @@ export const authjsSessionMiddleware: Get<[], UniversalMiddleware> =
* Auth.js route * Auth.js route
* @link {@see https://authjs.dev/getting-started/installation} * @link {@see https://authjs.dev/getting-started/installation}
**/ **/
export const authjsHandler = (() => async (request) => { export const authjsHandler = (() => async (request, context, runtime) => {
return Auth(request, authjsConfig); const env = getEnv(runtime);
return Auth(request, authjsConfig(env as Record<string, string>));
}) satisfies Get<[], UniversalHandler>; }) satisfies Get<[], UniversalHandler>;

@ -27,7 +27,7 @@ export const trpcHandler = ((endpoint) => (request, context, runtime) => {
); );
const jwt = await getToken({ const jwt = await getToken({
req, req,
secret: processEnv.AUTHJS_SECRET, secret: (env.AUTHJS_SECRET || processEnv.AUTHJS_SECRET) as string,
/** Needed to specify cookie name because for some reason in production /** Needed to specify cookie name because for some reason in production
* it wasn't reading the correct cookie but in development it was. It * it wasn't reading the correct cookie but in development it was. It
* was not straightforward to fix the name of the cookie in * was not straightforward to fix the name of the cookie in

Loading…
Cancel
Save