@ -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 ( ) ;
/ * * T O D O : t h e f o l l o w i n g s h o u l d n e v e r h a p p e n , b e c a u s e t h e a c c o u n t i n
/ * * T O D O : t h e f o l l o w i n g s h o u l d n e v e r h a p p e n , b e c a u s e t h e a c c o u n t i n
* 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 > ;