Files
evidencija-rezija/app/lib/auth.ts
Nikola Derežić 78a6c18ba5 add option to create location in all subsequent months
- Added toggle in LocationEditForm for adding locations to future months (disabled by default)
- Modified updateOrAddLocation action to support batch creation across subsequent months
- Only creates locations in months where no location with same name exists
- Added translations for toggle text in Croatian and English
- Fixed unused variable warning in deleteLocationById
- Improved auth.ts development comments for clarity

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-11 10:27:31 +02:00

125 lines
4.3 KiB
TypeScript

import NextAuth, { NextAuthConfig } from 'next-auth';
import GoogleProvider from 'next-auth/providers/google';
import LinkedinProvider from 'next-auth/providers/linkedin';
import { Session } from 'next-auth';
import { AuthenticatedUser } from './types/next-auth';
import { defaultLocale } from '../i18n';
export const myAuth = () => {
/**
Google auth does not work in development environment
- this is a hack to make it work in development environment
- it returns a fake session object which is used by the Next-Auth middleware
Instructions: when in dev environment, uncomment the following code snippet
- this will return a fake session object which is used by the Next-Auth middleware
- when in production environment, comment the code snippet back
Note: this is not a secure way to handle authentication, it is only for development purposes
- in production environment, the auth should be handled by the Next-Auth middleware
Code snippet:
const session:Session = {
user: {
id: "109754742613069927799",
name: "Nikola Derežić",
},
expires: "123",
};
return(Promise.resolve(session));
*/
return(auth());
}
export const authConfig: NextAuthConfig = {
callbacks: {
// method verifies if the user is logged in or not
// -> is called by Next-Auth when the midleware calls the `auth` method (exported below)
authorized({ auth, request: { nextUrl } }) {
const isLoggedIn = !!auth?.user;
return (isLoggedIn);
},
// method is called when the user is not logged in
// this is a hack which takes user ID and assigns it temporaty to the token, which is then used to extend Session.user
// see: https://stackoverflow.com/questions/70409219/get-user-id-from-session-in-next-auth-client
jwt({ token, account, user }) {
if (account) {
token.accessToken = account.access_token
token.id = user?.id
}
return token
},
// method is called after the JWT token is created
// this is a hack which takes user ID temporaty assigned to the token and assigns it to the Session.user
// see: https://stackoverflow.com/questions/70409219/get-user-id-from-session-in-next-auth-client
async session({ session, token }:{ session:Session, token:any }) {
if(session.user && token) {
session.user.id = token.id;
}
return session;
},
},
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
}),
// // config based on https://github.com/nextauthjs/next-auth/issues/8831
// LinkedinProvider({
// clientId: process.env.LINKEDIN_ID,
// clientSecret: process.env.LINKEDIN_SECRET,
// authorization: { params: { scope: 'email openid' } },
// issuer: 'https://www.linkedin.com',
// jwks_endpoint: "https://www.linkedin.com/oauth/openid/jwks",
// async profile(profile) {
// return {
// id: profile.sub,
// name: profile.name,
// firstname: profile.given_name,
// lastname: profile.family_name,
// email: profile.email
// }
// },
// })
],
secret: process.env.AUTH_SECRET,
trustHost: true, // needs to be set to false for the NextJS to work behing Traefik
session: {
// Use JSON Web Tokens for session instead of database sessions.
// This option can be used with or without a database for users/accounts.
// Note: `jwt` is automatically set to `true` if no database is specified.
strategy: 'jwt'
},
pages: {
signIn: `/${defaultLocale}/login`,
},
};
export const { auth, handlers: { GET, POST } } = NextAuth(authConfig);
export type AuthErrorMessage = {
message: string,
errors: {
message: string,
}
}
export const isAuthErrorMessage = (obj: any): obj is AuthErrorMessage => {
return (obj.message && obj.errors && obj.errors.message);
}
export const withUser = <T, A extends any[]>(fn: (user: AuthenticatedUser, ...args:A) => Promise<T>) => async (...args:A) => {
const session = await myAuth();
if(!session) {
throw new Error("Not authenticated")
}
const { user } = session;
return(fn(user, ...args));
}