I am trying to use Credentials Provider with NextJs ("next": "^12.0.7") and NextAuth ("next-auth": "^4.1.2"). I am writing this in typescript, and facing issues in getting the function correctly.
Here's my /pages/api/[...nextauth].ts
import NextAuth, { } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { verifyOTP } from "@/lib/otp";
// {
// user: {
// id: 1,
// username: null,
// phone: '+919876543210',
// phoneVerified: true,
// email: null,
// emailVerified: false,
// active: true,
// token: 'SOME TOKEN',
// createDate: null
// },
// result: 'approved'
// }
export default NextAuth({
pages: {
signIn: '/signup',
newUser: '/signup',
error: '/signup'
},
debug: false,
secret: "SOME_SECRET",
// Configure one or more authentication providers
providers: [
CredentialsProvider({
credentials: {
username: {label: "username", type: "text", placeholder: "markandre"},
phone: { label: "Phone ", type: "text", placeholder: "+919876543210" },
otp: { label: "OTP", type: "text" }
},
authorize: async (credentials, _req) => {
try {
const res = await verifyOTP(credentials!.phone,
credentials!.otp, credentials?.username);
if (res.result === "approved") {
return Promise.resolve( {
id: res.user.id,
email: res.user.email,
name: res.user.phone,
token: res.user.token
});
}
} catch (e: any) {
//const errorMessage = e.response.data.message;
//throw new Error(errorMessage);
return Promise.reject(null);
}
}
})
],
session: {
strategy: 'jwt',
maxAge: 3 * 60 * 60, // 3 hours
},
callbacks: {
jwt: async ({token, user}) => {
if (user) {
token.accessToken = user.token
}
return token;
},
session:async ({session, token}) => {
if (token) {
session.accessToken = token.accessToken;
}
return session;
}
},
events: {
signIn: async (message) => {
console.log('signIn', message);
},
signOut: async (message) => {
console.log('signOut', message);
},
createUser: async(message) => {
console.log('createUser', message);
},
updateUser: async(message) => {
console.log('updateUser', message);
},
linkAccount: async(message) => {
console.log('linkAccount',message);
},
session: async(message) => {
// console.log('session', message);
}
}
})
When I am building this app, I keep getting the error
./src/pages/api/auth/[...nextauth].ts:36:7
Type error: Type '(credentials: Record<"username" | "phone" | "otp", string> | undefined, _req: Pick<IncomingRequest, "headers" | "body" | "query" | "method">) => Promise<...>' is not assignable to type '(credentials: Record<"username" | "phone" | "otp", string> | undefined, req: Pick<IncomingRequest, "headers" | "body" | "query" | "method">) => Awaitable<...>'.
Type 'Promise<Omit<User, "id"> | null | undefined>' is not assignable to type 'Awaitable<Omit<User, "id"> | { id?: string | undefined; } | null>'.
Type 'Promise<Omit<User, "id"> | null | undefined>' is not assignable to type 'Omit<User, "id">'.
Index signature for type 'string' is missing in type 'Promise<Omit<User, "id"> | null | undefined>'.
34 | otp: { label: "OTP", type: "text" }
35 | },
> 36 | authorize: async (credentials, _req) => {
| ^
37 | try {
38 | const res = await verifyOTP(credentials!.phone,
39 | credentials!.otp, credentials?.username);
info - Checking validity of types .%
My .tsconfig
looks like below
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"removeComments": true,
"preserveConstEnums": true,
"strict": true,
"alwaysStrict": false,
"strictNullChecks": true,
"noUncheckedIndexedAccess": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"allowUnreachableCode": false,
"noFallthroughCasesInSwitch": true,
"target": "es5",
"outDir": "out",
"declaration": true,
"sourceMap": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"allowJs": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"jsx": "preserve",
"noEmit": true,
"isolatedModules": true,
"incremental": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@/public/*": ["./public/*"]
}
},
"exclude": ["./out/**/*", "./node_modules/**/*"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}
credentials
input, and your answer goes into details about return type, which is not the culprit here. – Hellkite