Files
mwitnessing/pages/api/auth/[...nextauth].ts
2024-05-07 10:28:54 +03:00

277 lines
10 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import NextAuth, { NextAuthOptions } from "next-auth"
import GoogleProvider from "next-auth/providers/google"
import FacebookProvider from "next-auth/providers/facebook"
import GithubProvider from "next-auth/providers/github"
import TwitterProvider from "next-auth/providers/twitter"
import Auth0Provider from "next-auth/providers/auth0"
import AppleProvider from "next-auth/providers/apple"
import EmailProvider from "next-auth/providers/email"
import CredentialsProvider from "next-auth/providers/credentials"
import { PrismaAdapter } from "@auth/prisma-adapter"
import bcrypt from "bcrypt"
//microsoft
import AzureADProvider from "next-auth/providers/azure-ad";
// https://next-auth.js.org/getting-started/client
const common = require("../../../src/helpers/common");
import { isLoggedIn, setAuthTokens, clearAuthTokens, getAccessToken, getRefreshToken } from 'axios-jwt'
import { create } from "domain"
//console.log("appleID:", process.env.APPLE_APP_ID);
// console.log(process.env.EMAIL_SERVER)
// For more information on each option (and a full list of options) go to
// https://next-auth.js.org/configuration/options
export const authOptions: NextAuthOptions = {
// https://next-auth.js.org/configuration/providers/oauth
site: process.env.NEXT_PUBLIC_PUBLIC_URL,
secret: process.env.NEXTAUTH_SECRET, // Ensure you have this set in your .env file
//adapter: PrismaAdapter(prisma),
providers: [
// register new URL at https://console.cloud.google.com/apis/credentials/oauthclient/926212607479-d3m8hm8f8esp3rf1639prskn445sa01v.apps.googleusercontent.com?project=grand-forge-108716
//Request details: redirect_uri=http://20.101.62.76:8005/api/auth/callback/google https://s.mwitnessingmwitnessing.com/
GoogleProvider({
clientId: process.env.GOOGLE_ID,
clientSecret: process.env.GOOGLE_SECRET,
authorization: {
params: {
prompt: "consent",
access_type: "offline",
response_type: "code"
}
}
}),
AppleProvider({
// clientId: process.env.APPLE_APP_ID,
// clientSecret: process.env.APPLE_SECRET
clientId: process.env.APPLE_APP_ID,
clientSecret: {
appleId: process.env.APPLE_APP_ID,
teamId: process.env.APPLE_TEAM_ID,
privateKey: process.env.APPLE_PK,
keyId: process.env.APPLE_KEY_ID,
}
}),
// AzureADProvider({
// clientId: process.env.AZURE_AD_CLIENT_ID,
// clientSecret: process.env.AZURE_AD_CLIENT_SECRET,
// tenantId: process.env.AZURE_AD_TENANT_ID,
// }),
CredentialsProvider({
id: 'credentials',
// The name to display on the sign in form (e.g. 'Sign in with...')
name: 'Credentials',
credentials: {
username: { label: "Потребител", type: "text", placeholder: "Потребителско име" },
password: { label: "Парола", type: "password" }
},
async authorize(credentials, req) {
//const user = { id: "1", name: "Администратора", email: "jsmith@example.com" }
//return user
// const res = await fetch("/your/endpoint", {
// method: 'POST',
// body: JSON.stringify(credentials),
// headers: { "Content-Type": "application/json" }
// })
// const user = await res.json()
// // If no error and we have user data, return it
// if (res.ok && user) {
// return user
// }
// // Return null if user data could not be retrieved
// return null
const users = [
{ id: "1", name: "admin", email: "admin@example.com", password: "admin123", role: "ADMIN", static: true },
{ id: "2", name: "krasi", email: "krasi@example.com", password: "krasi123", role: "ADMIN", static: true },
{ id: "3", name: "popov", email: "popov@example.com", password: "popov123", role: "ADMIN", static: true }
];
const user = users.find(user =>
user.name === credentials.username && user.password === credentials.password
);
if (user) {
return user;
}
else {
const prisma = common.getPrismaClient();
const user = await prisma.user.findUnique({ where: { email: credentials.username } });
if (user) {
const match = await bcrypt.compare(credentials?.password, user.passwordHashLocalAccount);
if (match) {
console.log("User authenticated successfully.");
//create access token
user.accessToken = await getAccessToken();
return user;
}
else {
console.log("Password mismatch.");
throw new Error('невалидна парола');
}
}
else {
const pub = await prisma.publisher.findUnique({ where: { email: credentials.username } });
if (pub) {
const passHash = await bcrypt.hash(credentials.password, 10);
const newUser = await prisma.user.create({
data: {
name: credentials.username,
email: credentials.username,
passwordHashLocalAccount: passHash
}
});
console.log("New local credential user created for publisher ", pub.firstName, " ", pub.lastName, " (", pub.email, ")");
return newUser;
}
else {
throw new Error("Не можем да намерим твоя имейл '" + credentials?.username + "' в участниците в ССОМ. Моля свържи се с нас за да те регистрираме ако искаш да ползваш този имейл.");
}
}
}
}
})
/*
EmailProvider({
server: {
host: "smtp.mailtrap.io",
port: 2525,
auth: {
user: "8ec69527ff2104",
pass: "c7bc05f171c96c"
}
},
// server: process.env.EMAIL_SERVER,
from: "noreply@example.com",
}),
// Temporarily removing the Apple provider from the demo site as the
// callback URL for it needs updating due to Vercel changing domains
/*
*/
//d-popov@abv.bg
// Auth0Provider({
// clientId: process.env.AUTH0_ID,
// clientSecret: process.env.AUTH0_SECRET,
// issuer: process.env.AUTH0_ISSUER,
// }),
],
theme: {
colorScheme: "light",
},
session: {
strategy: "jwt"
},
callbacks: {
// https://codevoweb.com/implement-authentication-with-nextauth-in-nextjs-14/
async signIn({ user, account, profile }) {
if (account.provider === 'credentials' && user?.static) {
return true;
}
var prisma = common.getPrismaClient();
console.log("[nextauth] signIn:", account.provider, user.email)
//if (account.provider === 'google' ) {
// Check user in your database and assign roles
const dbUser = await prisma.publisher.findUnique({
where: { email: user.email }
});
if (dbUser) {
// Assign roles from your database to the session
user.role = dbUser.role;
user.id = dbUser.id;
//user.permissions = dbUser.permissions;
const session = { ...user };
await prisma.publisher.update({
where: { id: dbUser.id },
data: { lastLogin: new Date() }
});
return true;
} else {
//user nor found in our database. deny access, showing error message. logout and redirect to message page
//throw new Error(`Твоят имейл '${user.email}' не е регистриран в системата. Моля свържи се с нас за да те регистрираме ако искаш да ползваш този имейл.`);
throw new Error(`UserNotFound&email=${encodeURIComponent(user?.email)}`);
}
},
// async redirect({ url, baseUrl, user }) {
// // Redirect based on the user or error
// console.log("[nextauth] redirect", url, baseUrl, user)
// if (user) {
// return url;
// } else if (url.includes('error=UserNotFound')) {
// // Redirect to a custom error page or display an error
// return `${baseUrl}/error=UserNotFound&mail=${encodeURIComponent(user?.email)}`;
// }
// return baseUrl;
// },
// Persist the OAuth access_token to the token right after signin
async jwt({ token, user, account, profile, isNewUser }) {
//!console.log("[nextauth] JWT", token, user)
//token.userRole = "adminer"
if (user) {
token.role = user.role;
token.id = user.id; //already done in session?
//token.name = user.name; already done in session (name, email, picture, sub)
}
if (account && user) {
token.accessToken = account.access_token; // Set the access token from the account object
token.provider = account.provider;
console.log("[nextauth] setting token.accessToken", token.accessToken);
setAuthTokens({
accessToken: account.accessToken,
refreshToken: account.refreshToken,
})
}
return token;
},
// Send properties to the client, like an access_token from a provider.
async session({ session, token, user }) {
//!console.log("[nextauth] session", token, user)
if (token) {
//session.user.role = token.role;
session.user.id = token.id;
session.user.role = token.role;
session.user.name = token.name || token.email;
}
if (user?.impersonating) {
// Add flag to session if user is being impersonated
session.user.impersonating = true;
}
// if (session?.user) {
// session.user.id = user.id; //duplicate
// }
return {
...session,
accessToken: token.accessToken
};
},
},
pages: {
signIn: "/auth/signin",
signOut: "/auth/signout",
error: "/message", // Error code passed in query string as ?error=
verifyRequest: "/auth/verify-request", // (used for check email message)
newUser: null // If set, new users will be directed here on first sign in
},
}
export default NextAuth(authOptions)