1.0.0
This commit is contained in:
parent
d1ca256f5a
commit
4b4b26a09a
5 changed files with 32 additions and 178 deletions
27
package.json
27
package.json
|
@ -1,13 +1,13 @@
|
|||
{
|
||||
"name": "@next-auth/mongodb-adapter",
|
||||
"version": "1.1.1",
|
||||
"description": "mongoDB adapter for next-auth.",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"name": "nextauth-mongodb-realm",
|
||||
"version": "1.0.0",
|
||||
"description": "mongoDB Realm adapter for next-auth.",
|
||||
"homepage": "https://git.skye.vg/me/nextauth-mongodb-realm",
|
||||
"repository": "https://git.skye.vg/me/nextauth-mongodb-realm",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
"url": "https://git.skye.vg/me/nextauth-mongodb-realm/issues"
|
||||
},
|
||||
"author": "Balázs Orbán <info@balazsorban.com>",
|
||||
"author": "Skye Green <support@skyevg.systems>",
|
||||
"main": "dist/index.js",
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
|
@ -22,8 +22,6 @@
|
|||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "./tests/test.sh",
|
||||
"test:watch": "./tests/test.sh -w",
|
||||
"build": "tsc"
|
||||
},
|
||||
"files": [
|
||||
|
@ -31,17 +29,12 @@
|
|||
"dist"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"mongodb": "^4.1.1",
|
||||
"realm-web": "^2.0.0",
|
||||
"next-auth": "^4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next-auth/adapter-test": "https://gitpkg.now.sh/nextauthjs/next-auth/packages/adapter-test?main",
|
||||
"@next-auth/tsconfig": "https://gitpkg.now.sh/nextauthjs/next-auth/packages/tsconfig?main",
|
||||
"jest": "^27.4.3",
|
||||
"mongodb": "^4.4.0",
|
||||
"next-auth": "^4.19.2"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@next-auth/adapter-test/jest"
|
||||
"realm-web": "^2.0.0",
|
||||
"next-auth": "^4"
|
||||
}
|
||||
}
|
||||
|
|
44
src/index.ts
44
src/index.ts
|
@ -1,5 +1,5 @@
|
|||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
import { ObjectId } from "mongodb"
|
||||
import * as Realm from "realm-web";
|
||||
|
||||
import type {
|
||||
Adapter,
|
||||
|
@ -8,7 +8,6 @@ import type {
|
|||
AdapterSession,
|
||||
VerificationToken,
|
||||
} from "next-auth/adapters"
|
||||
import type { MongoClient } from "mongodb"
|
||||
|
||||
export interface MongoDBAdapterOptions {
|
||||
collections?: {
|
||||
|
@ -17,7 +16,8 @@ export interface MongoDBAdapterOptions {
|
|||
Sessions?: string
|
||||
VerificationTokens?: string
|
||||
}
|
||||
databaseName?: string
|
||||
databaseName: string
|
||||
serviceName: string
|
||||
}
|
||||
|
||||
export const defaultCollections: Required<
|
||||
|
@ -56,31 +56,31 @@ export const format = {
|
|||
else if (key === "id") continue
|
||||
else newObject[key] = value
|
||||
}
|
||||
return newObject as T & { _id: ObjectId }
|
||||
return newObject as T & { _id: Realm.BSON.ObjectId }
|
||||
},
|
||||
}
|
||||
|
||||
/** Converts from string to ObjectId */
|
||||
export function _id(hex?: string) {
|
||||
if (hex?.length !== 24) return new ObjectId()
|
||||
return new ObjectId(hex)
|
||||
if (hex?.length !== 24) return new Realm.BSON.ObjectId()
|
||||
return new Realm.BSON.ObjectId(hex)
|
||||
}
|
||||
|
||||
export function MongoDBAdapter(
|
||||
client: Promise<MongoClient>,
|
||||
options: MongoDBAdapterOptions = {}
|
||||
client: Promise<Realm.User>,
|
||||
options: MongoDBAdapterOptions
|
||||
): Adapter {
|
||||
const { collections } = options
|
||||
const { from, to } = format
|
||||
|
||||
const db = (async () => {
|
||||
const _db = (await client).db(options.databaseName)
|
||||
const _db = (await client).mongoClient(options.serviceName).db(options.databaseName)
|
||||
const c = { ...defaultCollections, ...collections }
|
||||
return {
|
||||
U: _db.collection<AdapterUser>(c.Users),
|
||||
A: _db.collection<AdapterAccount>(c.Accounts),
|
||||
S: _db.collection<AdapterSession>(c.Sessions),
|
||||
V: _db.collection<VerificationToken>(c?.VerificationTokens),
|
||||
U: _db.collection<AdapterUser & { _id: Realm.BSON.ObjectId }>(c.Users),
|
||||
A: _db.collection<AdapterAccount & { _id: Realm.BSON.ObjectId }>(c.Accounts),
|
||||
S: _db.collection<AdapterSession & { _id: Realm.BSON.ObjectId }>(c.Sessions),
|
||||
V: _db.collection<VerificationToken & { _id: Realm.BSON.ObjectId }>(c?.VerificationTokens),
|
||||
}
|
||||
})()
|
||||
|
||||
|
@ -105,7 +105,7 @@ export function MongoDBAdapter(
|
|||
if (!account) return null
|
||||
const user = await (
|
||||
await db
|
||||
).U.findOne({ _id: new ObjectId(account.userId) })
|
||||
).U.findOne({ _id: new Realm.BSON.ObjectId(account.userId) })
|
||||
if (!user) return null
|
||||
return from<AdapterUser>(user)
|
||||
},
|
||||
|
@ -114,9 +114,9 @@ export function MongoDBAdapter(
|
|||
|
||||
const result = await (
|
||||
await db
|
||||
).U.findOneAndUpdate({ _id }, { $set: user }, { returnDocument: "after" })
|
||||
).U.findOneAndUpdate({ _id }, { $set: user }, { returnNewDocument: true })
|
||||
|
||||
return from<AdapterUser>(result.value!)
|
||||
return from<AdapterUser>(result!)
|
||||
},
|
||||
async deleteUser(id) {
|
||||
const userId = _id(id)
|
||||
|
@ -133,7 +133,7 @@ export function MongoDBAdapter(
|
|||
return account
|
||||
},
|
||||
async unlinkAccount(provider_providerAccountId) {
|
||||
const { value: account } = await (
|
||||
const account = await (
|
||||
await db
|
||||
).A.findOneAndDelete(provider_providerAccountId)
|
||||
return from<AdapterAccount>(account!)
|
||||
|
@ -143,7 +143,7 @@ export function MongoDBAdapter(
|
|||
if (!session) return null
|
||||
const user = await (
|
||||
await db
|
||||
).U.findOne({ _id: new ObjectId(session.userId) })
|
||||
).U.findOne({ _id: new Realm.BSON.ObjectId(session.userId) })
|
||||
if (!user) return null
|
||||
return {
|
||||
user: from<AdapterUser>(user),
|
||||
|
@ -163,12 +163,12 @@ export function MongoDBAdapter(
|
|||
).S.findOneAndUpdate(
|
||||
{ sessionToken: session.sessionToken },
|
||||
{ $set: session },
|
||||
{ returnDocument: "after" }
|
||||
{ returnNewDocument: true }
|
||||
)
|
||||
return from<AdapterSession>(result.value!)
|
||||
return from<AdapterSession>(result!)
|
||||
},
|
||||
async deleteSession(sessionToken) {
|
||||
const { value: session } = await (
|
||||
const session = await (
|
||||
await db
|
||||
).S.findOneAndDelete({
|
||||
sessionToken,
|
||||
|
@ -180,7 +180,7 @@ export function MongoDBAdapter(
|
|||
return data
|
||||
},
|
||||
async useVerificationToken(identifier_token) {
|
||||
const { value: verificationToken } = await (
|
||||
const verificationToken = await (
|
||||
await db
|
||||
).V.findOneAndDelete(identifier_token)
|
||||
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
import { runBasicTests } from "@next-auth/adapter-test"
|
||||
import { defaultCollections, format, MongoDBAdapter, _id } from "../src"
|
||||
import { MongoClient } from "mongodb"
|
||||
const name = "custom-test"
|
||||
const client = new MongoClient(`mongodb://localhost:27017/${name}`)
|
||||
const clientPromise = client.connect()
|
||||
|
||||
const collections = { ...defaultCollections, Users: "some_userz" }
|
||||
|
||||
runBasicTests({
|
||||
adapter: MongoDBAdapter(clientPromise, {
|
||||
collections,
|
||||
}),
|
||||
db: {
|
||||
async disconnect() {
|
||||
await client.db().dropDatabase()
|
||||
await client.close()
|
||||
},
|
||||
async user(id) {
|
||||
const user = await client
|
||||
.db()
|
||||
.collection(collections.Users)
|
||||
.findOne({ _id: _id(id) })
|
||||
|
||||
if (!user) return null
|
||||
return format.from(user)
|
||||
},
|
||||
async account(provider_providerAccountId) {
|
||||
const account = await client
|
||||
.db()
|
||||
.collection(collections.Accounts)
|
||||
.findOne(provider_providerAccountId)
|
||||
if (!account) return null
|
||||
return format.from(account)
|
||||
},
|
||||
async session(sessionToken) {
|
||||
const session = await client
|
||||
.db()
|
||||
.collection(collections.Sessions)
|
||||
.findOne({ sessionToken })
|
||||
if (!session) return null
|
||||
return format.from(session)
|
||||
},
|
||||
async verificationToken(identifier_token) {
|
||||
const token = await client
|
||||
.db()
|
||||
.collection(collections.VerificationTokens)
|
||||
.findOne(identifier_token)
|
||||
if (!token) return null
|
||||
const { _id, ...rest } = token
|
||||
return rest
|
||||
},
|
||||
},
|
||||
})
|
|
@ -1,51 +0,0 @@
|
|||
import { runBasicTests } from "@next-auth/adapter-test"
|
||||
import { defaultCollections, format, MongoDBAdapter, _id } from "../src"
|
||||
import { MongoClient } from "mongodb"
|
||||
|
||||
const name = "test"
|
||||
const client = new MongoClient(`mongodb://localhost:27017/${name}`)
|
||||
const clientPromise = client.connect()
|
||||
|
||||
runBasicTests({
|
||||
adapter: MongoDBAdapter(clientPromise),
|
||||
db: {
|
||||
async disconnect() {
|
||||
await client.db().dropDatabase()
|
||||
await client.close()
|
||||
},
|
||||
async user(id) {
|
||||
const user = await client
|
||||
.db()
|
||||
.collection(defaultCollections.Users)
|
||||
.findOne({ _id: _id(id) })
|
||||
|
||||
if (!user) return null
|
||||
return format.from(user)
|
||||
},
|
||||
async account(provider_providerAccountId) {
|
||||
const account = await client
|
||||
.db()
|
||||
.collection(defaultCollections.Accounts)
|
||||
.findOne(provider_providerAccountId)
|
||||
if (!account) return null
|
||||
return format.from(account)
|
||||
},
|
||||
async session(sessionToken) {
|
||||
const session = await client
|
||||
.db()
|
||||
.collection(defaultCollections.Sessions)
|
||||
.findOne({ sessionToken })
|
||||
if (!session) return null
|
||||
return format.from(session)
|
||||
},
|
||||
async verificationToken(identifier_token) {
|
||||
const token = await client
|
||||
.db()
|
||||
.collection(defaultCollections.VerificationTokens)
|
||||
.findOne(identifier_token)
|
||||
if (!token) return null
|
||||
const { _id, ...rest } = token
|
||||
return rest
|
||||
},
|
||||
},
|
||||
})
|
|
@ -1,34 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
CONTAINER_NAME=next-auth-mongodb-test
|
||||
|
||||
JEST_WATCH=false
|
||||
|
||||
# Is the watch flag passed to the script?
|
||||
while getopts w flag
|
||||
do
|
||||
case "${flag}" in
|
||||
w) JEST_WATCH=true;;
|
||||
*) continue;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Start db
|
||||
docker run -d --rm -p 27017:27017 --name ${CONTAINER_NAME} mongo
|
||||
|
||||
echo "Waiting 3 sec for db to start..."
|
||||
sleep 3
|
||||
|
||||
if $JEST_WATCH; then
|
||||
# Run jest in watch mode
|
||||
npx jest tests --watch
|
||||
# Only stop the container after jest has been quit
|
||||
docker stop "${CONTAINER_NAME}"
|
||||
else
|
||||
# Always stop container, but exit with 1 when tests are failing
|
||||
if npx jest;then
|
||||
docker stop ${CONTAINER_NAME}
|
||||
else
|
||||
docker stop ${CONTAINER_NAME} && exit 1
|
||||
fi
|
||||
fi
|
Loading…
Reference in a new issue