Created
October 15, 2021 21:40
-
-
Save Tsugami/23f83e31db9fb4c1f786f9a857435048 to your computer and use it in GitHub Desktop.
MongooseNextAuthAdapter.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import mongoose, { Types, Document } from 'mongoose'; | |
import { | |
Adapter, | |
AdapterUser, | |
AdapterSession, | |
VerificationToken as AdapterVerificationToken, | |
} from 'next-auth/adapters'; | |
import { Account as AdapterAccount } from 'next-auth'; | |
import UserModel, { IUser } from '../modules/user/UserModel'; | |
import AccountModel, { IAccount } from '../modules/auth/AccountModel'; | |
import SessionModel, { ISession } from '../modules/auth/SessionModel'; | |
import VerificationTokenModel from '../modules/auth/VerificationTokenModel'; | |
function _id(hex?: string) { | |
if (hex?.length !== 24) return new Types.ObjectId(); | |
return new Types.ObjectId(hex); | |
} | |
const from = <A>(data: Document): A => { | |
return { | |
...data, | |
id: data._id, | |
} as unknown as A; | |
}; | |
const adapterUser = (user: IUser): AdapterUser => from<AdapterUser>(user); | |
const adapterAccount = (account: IAccount): AdapterAccount => from<AdapterAccount>(account); | |
const adapterSession = (session: ISession): AdapterSession => from<AdapterSession>(session); | |
const MongooseNextAuthAdapter = (): Adapter => { | |
return { | |
createUser: async (user) => { | |
const newUser = await UserModel.create(user); | |
return adapterUser(newUser); | |
}, | |
getUser: async (id) => { | |
const user = await UserModel.findOne({ _id: _id(id) }); | |
if (!user) return null; | |
return adapterUser(user); | |
}, | |
getUserByEmail: async (email) => { | |
const user = await UserModel.findOne({ email }); | |
if (!user) return null; | |
return adapterUser(user); | |
}, | |
getUserByAccount: async (provider) => { | |
const account = await AccountModel.findOne(provider); | |
if (!account) return null; | |
const user = await UserModel.findOne({ _id: account.userId }); | |
if (!user) return null; | |
return adapterUser(user); | |
}, | |
async updateUser(data) { | |
await UserModel.updateOne({ _id: _id(data.id) }, { $set: data }); | |
return MongooseNextAuthAdapter().getUser(data.id as string) as AdapterUser; | |
}, | |
deleteUser: async (userId) => { | |
const session = await mongoose.startSession(); | |
AccountModel.deleteMany({ userId }, { session }); | |
SessionModel.deleteMany({ userId }, { session }); | |
UserModel.deleteOne({ _id: userId }, { session }); | |
await session.endSession(); | |
}, | |
linkAccount: async (account) => { | |
const newaAcount = await AccountModel.create(account); | |
return adapterAccount(newaAcount); | |
}, | |
async unlinkAccount(accountProvider) { | |
await AccountModel.deleteOne(accountProvider); | |
}, | |
createSession: async (data) => { | |
const newSession = await SessionModel.create(data); | |
return adapterSession(newSession); | |
}, | |
getSessionAndUser: async (sessionToken) => { | |
const session = await SessionModel.findOne({ sessionToken: sessionToken }); | |
if (!session) return null; | |
const user = await UserModel.findOne({ _id: session.userId }); | |
if (!user) return null; | |
return { session: adapterSession(session), user: adapterUser(user) }; | |
}, | |
async updateSession(data) { | |
await SessionModel.updateOne( | |
{ | |
sessionToken: data.sessionToken, | |
}, | |
{ $set: data }, | |
); | |
const session = await SessionModel.findOne({ | |
sessionToken: data.sessionToken, | |
}); | |
return session ? adapterSession(session) : null; | |
}, | |
async deleteSession(sessionToken) { | |
await SessionModel.deleteOne({ sessionToken }); | |
}, | |
async createVerificationToken(data) { | |
await VerificationTokenModel.create(data); | |
return data; | |
}, | |
async useVerificationToken(identifier_token) { | |
const data = await VerificationTokenModel.findOne(identifier_token); | |
if (!data) return null; | |
await VerificationTokenModel.deleteOne(identifier_token); | |
return from<AdapterVerificationToken>(data); | |
}, | |
}; | |
}; | |
export default MongooseNextAuthAdapter; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment