mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
Compare commits
2 Commits
@next-auth
...
feat/hasur
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be6a85d7b5 | ||
|
|
946717523b |
@@ -1161,9 +1161,9 @@ isexe@^2.0.0:
|
||||
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||
|
||||
jose@^4.1.4, jose@^4.3.7:
|
||||
version "4.9.3"
|
||||
resolved "https://registry.yarnpkg.com/jose/-/jose-4.9.3.tgz#890abd3f26725fe0f2aa720bc2f7835702b624db"
|
||||
integrity sha512-f8E/z+T3Q0kA9txzH2DKvH/ds2uggcw0m3vVPSB9HrSkrQ7mojjifvS7aR8cw+lQl2Fcmx9npwaHpM/M3GD8UQ==
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/jose/-/jose-4.5.0.tgz#92829d8cf846351eb55aaaf94f252fb1d191f2d5"
|
||||
integrity sha512-GFcVFQwYQKbQTUOo2JlpFGXTkgBw26uzDsRMD2q1WgSKNSnpKS9Ug7bdQ8dS+p4sZHNH6iRPu6WK2jLIjspaMA==
|
||||
|
||||
js-yaml@^4.1.0:
|
||||
version "4.1.0"
|
||||
|
||||
@@ -67,7 +67,7 @@ export default function Component() {
|
||||
|
||||
Due to the way how Next.js handles `getServerSideProps` and `getInitialProps`, every protected page load has to make a server-side request to check if the session is valid and then generate the requested page (SSR). This increases server load, and if you are good with making the requests from the client, there is an alternative. You can use `useSession` in a way that makes sure you always have a valid session. If after the initial loading state there was no session found, you can define the appropriate action to respond.
|
||||
|
||||
The default behavior is to redirect the user to the sign-in page, from where - after a successful login - they will be sent back to the page they started on. You can also define an `onUnauthenticated()` callback, if you would like to do something else:
|
||||
The default behavior is to redirect the user to the sign-in page, from where - after a successful login - they will be sent back to the page they started on. You can also define an `onFail()` callback, if you would like to do something else:
|
||||
|
||||
#### Example
|
||||
|
||||
|
||||
@@ -24,11 +24,7 @@ providers: [
|
||||
AtlassianProvider({
|
||||
clientId: process.env.ATLASSIAN_CLIENT_ID,
|
||||
clientSecret: process.env.ATLASSIAN_CLIENT_SECRET,
|
||||
authorization: {
|
||||
params: {
|
||||
scope: "write:jira-work read:jira-work read:jira-user offline_access read:me"
|
||||
}
|
||||
}
|
||||
scope: "write:jira-work read:jira-work read:jira-user offline_access read:me"
|
||||
})
|
||||
]
|
||||
...
|
||||
|
||||
@@ -42,19 +42,13 @@ export default function Page() {
|
||||
|
||||
### Next.js (Middleware)
|
||||
|
||||
With NextAuth.js 4.2.0 and Next.js 12, you can now protect your pages via the middleware pattern more easily. If you would like to protect all pages, you can create a `_middleware.js` file in your root `pages` directory which looks like this:
|
||||
With NextAuth.js 4.2.0 and Next.js 12, you can now protect your pages via the middleware pattern more easily. If you would like to protect all pages, you can create a `_middleware.js` file in your root `pages` directory which looks like this.
|
||||
|
||||
```js title="/middleware.js"
|
||||
export { default } from "next-auth/middleware"
|
||||
```
|
||||
|
||||
If you only want to secure certain pages, export a `config` object with a `matcher`:
|
||||
|
||||
```js
|
||||
export { default } from "next-auth/middleware"
|
||||
|
||||
export const config = { matcher: ["/dashboard"] }
|
||||
```
|
||||
Otherwise, if you only want to protect a subset of pages, you could put it in a subdirectory as well, for example in `/pages/admin/_middleware.js` would protect all pages under `/admin`.
|
||||
|
||||
For the time being, the `withAuth` middleware only supports `"jwt"` as [session strategy](https://next-auth.js.org/configuration/options#session).
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"build:app": "turbo run build --filter=next-auth-app --include-dependencies",
|
||||
"build": "turbo run build --filter=next-auth --filter=@next-auth/* --no-deps",
|
||||
"lint": "turbo run lint --filter=!next-auth-docs --parallel",
|
||||
"test": "turbo run test --concurrency=1 --filter=!@next-auth/pouchdb-adapter --filter=!@next-auth/upstash-redis-adapter --filter=!next-auth-* --filter=[HEAD^1]",
|
||||
"test": "turbo run test --concurrency=1 --filter=!@next-auth/pouchdb-adapter --filter=!@next-auth/mikro-orm-adapter --filter=!@next-auth/upstash-redis-adapter --filter=!next-auth-* --filter=[HEAD^1]",
|
||||
"clean": "turbo run clean --no-cache",
|
||||
"dev:app": "turbo run dev --parallel --continue --filter=next-auth-app...",
|
||||
"dev:docs": "turbo run dev --filter=next-auth-docs",
|
||||
|
||||
10
packages/adapter-hasura/README.md
Normal file
10
packages/adapter-hasura/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
<p align="center">
|
||||
<br/>
|
||||
<a href="https://next-auth.js.org" target="_blank"><img height="64px" src="https://next-auth.js.org/img/logo/logo-sm.png" /></a> <img height="64px" src="https://hasura.io/brand-assets/hasura-logo-primary-dark.svg" />
|
||||
<h3 align="center"><b>Hasura Adapter</b> - NextAuth.js</h3>
|
||||
<p align="center">
|
||||
Open Source. Full Stack. Own Your Data.
|
||||
</p>
|
||||
</p>
|
||||
|
||||
TODO
|
||||
44
packages/adapter-hasura/package.json
Normal file
44
packages/adapter-hasura/package.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "@next-auth/hasura-adapter",
|
||||
"version": "1.0.0",
|
||||
"description": "Hasura adapter for next-auth.",
|
||||
"homepage": "https://next-auth.js.org",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
},
|
||||
"author": "Balázs Orbán <info@balazsorban.com>",
|
||||
"contributors": [],
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
"dist",
|
||||
"index.d.ts"
|
||||
],
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
"next-auth",
|
||||
"next.js",
|
||||
"hasura",
|
||||
"graphql"
|
||||
],
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "tsc --watch",
|
||||
"build": "tsc",
|
||||
"test": "./tests/test.sh"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"next-auth": "^4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next-auth/adapter-test": "workspace:*",
|
||||
"@next-auth/tsconfig": "workspace:*",
|
||||
"next-auth": "workspace:*"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@next-auth/adapter-test/jest"
|
||||
}
|
||||
}
|
||||
49
packages/adapter-hasura/src/graphql/models.ts
Normal file
49
packages/adapter-hasura/src/graphql/models.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import type { Account } from "next-auth"
|
||||
import type {
|
||||
AdapterSession,
|
||||
AdapterUser,
|
||||
VerificationToken,
|
||||
} from "next-auth/adapters"
|
||||
|
||||
export interface Model<T> {
|
||||
name: string
|
||||
fields: Array<keyof T>
|
||||
}
|
||||
|
||||
export interface Models {
|
||||
User: Model<AdapterUser>
|
||||
Account: Model<Account>
|
||||
Session: Model<AdapterSession>
|
||||
VerificationToken: Model<VerificationToken>
|
||||
}
|
||||
|
||||
export const models: Models = {
|
||||
User: {
|
||||
name: "User",
|
||||
fields: ["email", "id", "image", "name", "emailVerified"],
|
||||
},
|
||||
Account: {
|
||||
name: "Account",
|
||||
fields: [
|
||||
"id",
|
||||
"type",
|
||||
"provider",
|
||||
"providerAccountId",
|
||||
"expires_at",
|
||||
"token_type",
|
||||
"scope",
|
||||
"access_token",
|
||||
"refresh_token",
|
||||
"id_token",
|
||||
"session_state",
|
||||
],
|
||||
},
|
||||
Session: {
|
||||
name: "Session",
|
||||
fields: ["expires", "id", "sessionToken"],
|
||||
},
|
||||
VerificationToken: {
|
||||
name: "VerificationToken",
|
||||
fields: ["identifier", "token", "expires"],
|
||||
},
|
||||
}
|
||||
1
packages/adapter-hasura/src/graphql/schema.gql
Normal file
1
packages/adapter-hasura/src/graphql/schema.gql
Normal file
@@ -0,0 +1 @@
|
||||
# TODO
|
||||
209
packages/adapter-hasura/src/index.ts
Normal file
209
packages/adapter-hasura/src/index.ts
Normal file
@@ -0,0 +1,209 @@
|
||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||
/* eslint-disable @typescript-eslint/no-base-to-string */
|
||||
import { format } from "./utils"
|
||||
import { Models, Model, models } from "./graphql/models"
|
||||
|
||||
import type { Adapter, AdapterUser } from "next-auth/adapters"
|
||||
import type { Account } from "next-auth"
|
||||
|
||||
export type { Models, Model }
|
||||
|
||||
export interface HasuraClientOptions {
|
||||
/** GraphQL endpoint */
|
||||
url: string
|
||||
/**
|
||||
* `X-Hasura-Admin-Secret` header value
|
||||
*
|
||||
* [Securing the GraphQL endpoint](https://hasura.io/docs/latest/deployment/securing-graphql-endpoint/)
|
||||
*/
|
||||
adminSecret: string
|
||||
}
|
||||
|
||||
export interface HasuraAdapterOptions {
|
||||
client: HasuraClientOptions
|
||||
models?: Partial<Models>
|
||||
}
|
||||
|
||||
export function HasuraAdapter(options: HasuraAdapterOptions): Adapter {
|
||||
const c = client(options.client)
|
||||
const m: Models = {
|
||||
User: { ...models.User, ...options.models?.User },
|
||||
Account: { ...models.Account, ...options.models?.Account },
|
||||
Session: { ...models.Session, ...options.models?.Session },
|
||||
VerificationToken: {
|
||||
...models.VerificationToken,
|
||||
...options.models?.VerificationToken,
|
||||
},
|
||||
}
|
||||
return {
|
||||
async createUser(data) {
|
||||
const result = await c.run<AdapterUser[]>(
|
||||
/* GraphQL */ `
|
||||
mutation ($data: [${m.User.name}_insert_input!]!) {
|
||||
insert_${m.User.name}(objects: $data) {
|
||||
returning {
|
||||
${m.User.fields.join(" ")}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ data }
|
||||
)
|
||||
return format.from(result?.[0])
|
||||
},
|
||||
async getUser(id) {
|
||||
const result = await c.run<AdapterUser>(
|
||||
/* GraphQL */ `
|
||||
query ($id: String!) {
|
||||
${m.User.name}(where: { id: { _eq: $id } }) {
|
||||
${m.User.fields.join(" ")}
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ id }
|
||||
)
|
||||
|
||||
return format.from(result)
|
||||
},
|
||||
async getUserByEmail(email) {
|
||||
const result = await c.run<AdapterUser[]>(
|
||||
/* GraphQL */ `
|
||||
query ($email: String!) {
|
||||
${m.User.name}(where: { email: { _eq: $email } }) {
|
||||
${m.User.fields.join(" ")}
|
||||
}
|
||||
}
|
||||
`,
|
||||
{ email }
|
||||
)
|
||||
return result?.[0] ?? null
|
||||
},
|
||||
async getUserByAccount(provider_providerAccountId) {
|
||||
const result = await c.run<Array<AdapterUser & { Accounts: Account }>>(
|
||||
/* GraphQL */ `
|
||||
query getUserByAccount($providerAccountId: String!, $provider: String!) {
|
||||
${m.User.name}(
|
||||
where: {Accounts: {providerAccountId: {_eq: $providerAccountId}, provider: {_eq: $provider}}}
|
||||
) {
|
||||
${m.User.fields.join(" ")}
|
||||
}
|
||||
}
|
||||
`,
|
||||
provider_providerAccountId
|
||||
)
|
||||
|
||||
if (!result?.length) return null
|
||||
const { Accounts: _, ...user } = result[0]
|
||||
return user
|
||||
},
|
||||
async updateUser({ id, ...input }) {
|
||||
throw new HasuraAdapterError("`updateUser` not implemented")
|
||||
},
|
||||
async deleteUser(id) {
|
||||
throw new HasuraAdapterError("`deleteUser` not implemented")
|
||||
},
|
||||
async linkAccount(data) {
|
||||
throw new HasuraAdapterError("`linkAccount` not implemented")
|
||||
},
|
||||
async unlinkAccount(provider_providerAccountId) {
|
||||
throw new HasuraAdapterError("`unlinkAccount` not implemented")
|
||||
},
|
||||
async getSessionAndUser(sessionToken) {
|
||||
throw new HasuraAdapterError("`getSessionAndUser` not implemented")
|
||||
},
|
||||
async createSession(data) {
|
||||
throw new HasuraAdapterError("`createSession` not implemented")
|
||||
},
|
||||
async updateSession({ sessionToken, ...input }) {
|
||||
throw new HasuraAdapterError("`updateSession` not implemented")
|
||||
},
|
||||
async deleteSession(sessionToken) {
|
||||
throw new HasuraAdapterError("`deleteSession` not implemented")
|
||||
},
|
||||
async createVerificationToken(input) {
|
||||
throw new HasuraAdapterError("`createVerificationToken` not implemented")
|
||||
},
|
||||
async useVerificationToken(params) {
|
||||
throw new HasuraAdapterError("`useVerificationToken` not implemented")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export class HasuraAdapterError extends Error {
|
||||
name = "HasuraAdapterError"
|
||||
query?: string
|
||||
variables?: any
|
||||
constructor(
|
||||
e: Error | string | Array<Error | string>,
|
||||
query?: string,
|
||||
variables?: any
|
||||
) {
|
||||
// @ts-expect-error
|
||||
super(Array.isArray(e) ? e.map((e) => e.message ?? e).join("\n") : e.m ?? e)
|
||||
this.query = query
|
||||
this.variables = variables
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
name: this.name,
|
||||
message: this.message,
|
||||
query: this.query,
|
||||
variables: this.variables,
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
const items = [
|
||||
this.message,
|
||||
this.query,
|
||||
JSON.stringify(this.variables, null, 2),
|
||||
].filter(Boolean)
|
||||
return `${this.name}: ${items.join("\n")}`
|
||||
}
|
||||
}
|
||||
|
||||
export function client(options: HasuraClientOptions) {
|
||||
if (!globalThis.fetch) {
|
||||
throw new HasuraAdapterError("Please provide a `fetch` implementation")
|
||||
}
|
||||
|
||||
const { url, adminSecret } = options
|
||||
|
||||
if (!adminSecret) {
|
||||
throw new HasuraAdapterError("Please provide an API key")
|
||||
}
|
||||
|
||||
if (!url) {
|
||||
throw new HasuraAdapterError("Please provide a GraphQL endpoint")
|
||||
}
|
||||
|
||||
return {
|
||||
async run<T>(
|
||||
query: string,
|
||||
variables?: Record<string, any>
|
||||
): Promise<T | null> {
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"X-Hasura-Admin-Secret": adminSecret,
|
||||
},
|
||||
body: JSON.stringify({ query, variables }),
|
||||
})
|
||||
|
||||
const { data = {}, errors } = await response.json()
|
||||
if (errors?.length) {
|
||||
throw new HasuraAdapterError(errors, query, variables)
|
||||
}
|
||||
return Object.values(data)[0] as any
|
||||
} catch (error) {
|
||||
if (error instanceof HasuraAdapterError) throw error
|
||||
throw new HasuraAdapterError(error as Error, query, variables)
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export { format, models }
|
||||
26
packages/adapter-hasura/src/utils.ts
Normal file
26
packages/adapter-hasura/src/utils.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
// https://github.com/honeinc/is-iso-date/blob/master/index.js
|
||||
const isoDateRE =
|
||||
/(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))|(\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d([+-][0-2]\d:[0-5]\d|Z))/
|
||||
|
||||
function isDate(value: any) {
|
||||
return value && isoDateRE.test(value) && !isNaN(Date.parse(value))
|
||||
}
|
||||
|
||||
export const format = {
|
||||
from<T extends Record<string, any> | null>(
|
||||
data?: T
|
||||
): T extends null ? null : T {
|
||||
if (!data) return null as any
|
||||
const newObject: Record<string, unknown> = {}
|
||||
for (const key in data) {
|
||||
const value = data[key]
|
||||
if (isDate(value)) {
|
||||
newObject[key] = new Date(value)
|
||||
} else {
|
||||
newObject[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
return newObject as any
|
||||
},
|
||||
}
|
||||
8
packages/adapter-hasura/tsconfig.eslint.json
Normal file
8
packages/adapter-hasura/tsconfig.eslint.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"include": ["tests", "src"],
|
||||
"exclude": [
|
||||
"./*.js",
|
||||
"./*.d.ts",
|
||||
]
|
||||
}
|
||||
15
packages/adapter-hasura/tsconfig.json
Normal file
15
packages/adapter-hasura/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"extends": "@next-auth/tsconfig/tsconfig.adapters.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"outDir": "dist"
|
||||
},
|
||||
"include": [
|
||||
"."
|
||||
],
|
||||
"exclude": [
|
||||
"tests",
|
||||
"dist",
|
||||
"jest.config.js"
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@next-auth/mikro-orm-adapter",
|
||||
"version": "3.0.0",
|
||||
"version": "2.0.1",
|
||||
"description": "MikroORM adapter for next-auth.",
|
||||
"homepage": "https://next-auth.js.org",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
@@ -32,22 +32,22 @@
|
||||
"dist"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"@mikro-orm/core": "^5",
|
||||
"@mikro-orm/core": "^5.0.2",
|
||||
"next-auth": "^4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@mikro-orm/core": "^5",
|
||||
"@mikro-orm/sqlite": "^5",
|
||||
"@mikro-orm/core": "^5.0.2",
|
||||
"@mikro-orm/sqlite": "^5.0.2",
|
||||
"@next-auth/adapter-test": "workspace:*",
|
||||
"@next-auth/tsconfig": "workspace:*",
|
||||
"@types/uuid": ">=8",
|
||||
"jest": "^29",
|
||||
"@types/uuid": "^8.3.3",
|
||||
"jest": "^27.4.3",
|
||||
"next-auth": "workspace:*"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": "^9"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@next-auth/adapter-test/jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"uuid": "^8.3.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
OneToMany,
|
||||
Collection,
|
||||
ManyToOne,
|
||||
types,
|
||||
} from "@mikro-orm/core"
|
||||
|
||||
import type { DefaultAccount } from "next-auth"
|
||||
@@ -30,56 +29,55 @@ export class User implements RemoveIndex<AdapterUser> {
|
||||
@PrimaryKey()
|
||||
id: string = randomUUID()
|
||||
|
||||
@Property({ type: types.string, nullable: true })
|
||||
@Property({ nullable: true })
|
||||
name?: string
|
||||
|
||||
@Property({ type: types.string, nullable: true })
|
||||
@Property({ nullable: true })
|
||||
@Unique()
|
||||
email?: string
|
||||
|
||||
@Property({ type: types.datetime, nullable: true })
|
||||
@Property({ type: "Date", nullable: true })
|
||||
emailVerified: Date | null = null
|
||||
|
||||
@Property({ type: types.string, nullable: true })
|
||||
@Property({ nullable: true })
|
||||
image?: string
|
||||
|
||||
@OneToMany({
|
||||
entity: 'Session',
|
||||
mappedBy: (session: Session) => session.user,
|
||||
entity: () => Session,
|
||||
mappedBy: (session) => session.user,
|
||||
hidden: true,
|
||||
orphanRemoval: true,
|
||||
})
|
||||
sessions = new Collection<Session, object>(this)
|
||||
sessions = new Collection<Session>(this)
|
||||
|
||||
@OneToMany({
|
||||
entity: 'Account',
|
||||
mappedBy: (account: Account) => account.user,
|
||||
entity: () => Account,
|
||||
mappedBy: (account) => account.user,
|
||||
hidden: true,
|
||||
orphanRemoval: true,
|
||||
})
|
||||
accounts = new Collection<Account, object>(this)
|
||||
accounts = new Collection<Account>(this)
|
||||
}
|
||||
|
||||
@Entity()
|
||||
export class Session implements AdapterSession {
|
||||
@PrimaryKey()
|
||||
@Property({ type: types.string })
|
||||
id: string = randomUUID()
|
||||
|
||||
@ManyToOne({
|
||||
entity: 'User',
|
||||
entity: () => User,
|
||||
hidden: true,
|
||||
onDelete: "cascade",
|
||||
})
|
||||
user!: User
|
||||
|
||||
@Property({ type: types.string, persist: false })
|
||||
@Property({ persist: false })
|
||||
userId!: string
|
||||
|
||||
@Property({ type: 'Date' })
|
||||
@Property()
|
||||
expires!: Date
|
||||
|
||||
@Property({ type: types.string })
|
||||
@Property()
|
||||
@Unique()
|
||||
sessionToken!: string
|
||||
}
|
||||
@@ -88,47 +86,46 @@ export class Session implements AdapterSession {
|
||||
@Unique({ properties: ["provider", "providerAccountId"] })
|
||||
export class Account implements RemoveIndex<DefaultAccount> {
|
||||
@PrimaryKey()
|
||||
@Property({ type: types.string })
|
||||
id: string = randomUUID()
|
||||
|
||||
@ManyToOne({
|
||||
entity: 'User',
|
||||
entity: () => User,
|
||||
hidden: true,
|
||||
onDelete: "cascade",
|
||||
})
|
||||
user!: User
|
||||
|
||||
@Property({ type: types.string, persist: false })
|
||||
@Property({ persist: false })
|
||||
userId!: string
|
||||
|
||||
@Property({ type: types.string })
|
||||
@Enum()
|
||||
type!: ProviderType
|
||||
|
||||
@Property({ type: types.string })
|
||||
@Property()
|
||||
provider!: string
|
||||
|
||||
@Property({ type: types.string })
|
||||
@Property()
|
||||
providerAccountId!: string
|
||||
|
||||
@Property({ type: types.string, nullable: true })
|
||||
@Property({ nullable: true })
|
||||
refresh_token?: string
|
||||
|
||||
@Property({ type: types.string, nullable: true })
|
||||
@Property({ nullable: true })
|
||||
access_token?: string
|
||||
|
||||
@Property({ type: types.integer, nullable: true })
|
||||
@Property({ nullable: true })
|
||||
expires_at?: number
|
||||
|
||||
@Property({ type: types.string, nullable: true })
|
||||
@Property({ nullable: true })
|
||||
token_type?: string
|
||||
|
||||
@Property({ type: types.string, nullable: true })
|
||||
@Property({ nullable: true })
|
||||
scope?: string
|
||||
|
||||
@Property({ type: types.text, nullable: true })
|
||||
@Property({ nullable: true })
|
||||
id_token?: string
|
||||
|
||||
@Property({ type: types.string, nullable: true })
|
||||
@Property({ nullable: true })
|
||||
session_state?: string
|
||||
}
|
||||
|
||||
@@ -136,12 +133,12 @@ export class Account implements RemoveIndex<DefaultAccount> {
|
||||
@Unique({ properties: ["token", "identifier"] })
|
||||
export class VerificationToken implements AdapterVerificationToken {
|
||||
@PrimaryKey()
|
||||
@Property({ type: types.string })
|
||||
@Property()
|
||||
token!: string
|
||||
|
||||
@Property({ type: 'Date' })
|
||||
@Property()
|
||||
expires!: Date
|
||||
|
||||
@Property({ type: types.string })
|
||||
@Property()
|
||||
identifier!: string
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { MikroORM, wrap } from "@mikro-orm/core"
|
||||
|
||||
import * as defaultEntities from "./entities"
|
||||
|
||||
export { defaultEntities }
|
||||
export * as defaultEntities from "./entities"
|
||||
|
||||
/**
|
||||
* The MikroORM adapter accepts a MikroORM configuration and returns a NextAuth adapter.
|
||||
|
||||
@@ -1,591 +0,0 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`run migrations: createSchemaSQL 1`] = `
|
||||
"pragma foreign_keys = off;
|
||||
|
||||
create table \`user\` (\`id\` text not null, \`name\` text null, \`email\` text null, \`email_verified\` datetime null, \`image\` text null, primary key (\`id\`));
|
||||
create unique index \`user_email_unique\` on \`user\` (\`email\`);
|
||||
|
||||
create table \`session\` (\`id\` text not null, \`user_id\` text not null, \`expires\` datetime not null, \`session_token\` text not null, constraint \`session_user_id_foreign\` foreign key(\`user_id\`) references \`user\`(\`id\`) on delete cascade on update cascade, primary key (\`id\`));
|
||||
create index \`session_user_id_index\` on \`session\` (\`user_id\`);
|
||||
create unique index \`session_session_token_unique\` on \`session\` (\`session_token\`);
|
||||
|
||||
create table \`account\` (\`id\` text not null, \`user_id\` text not null, \`type\` text not null, \`provider\` text not null, \`provider_account_id\` text not null, \`refresh_token\` text null, \`access_token\` text null, \`expires_at\` integer null, \`token_type\` text null, \`scope\` text null, \`id_token\` text null, \`session_state\` text null, constraint \`account_user_id_foreign\` foreign key(\`user_id\`) references \`user\`(\`id\`) on delete cascade on update cascade, primary key (\`id\`));
|
||||
create index \`account_user_id_index\` on \`account\` (\`user_id\`);
|
||||
create unique index \`account_provider_provider_account_id_unique\` on \`account\` (\`provider\`, \`provider_account_id\`);
|
||||
|
||||
create table \`verification_token\` (\`token\` text not null, \`expires\` datetime not null, \`identifier\` text not null, primary key (\`token\`));
|
||||
create unique index \`verification_token_token_identifier_unique\` on \`verification_token\` (\`token\`, \`identifier\`);
|
||||
|
||||
pragma foreign_keys = on;
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`run migrations: targetSchema 1`] = `
|
||||
{
|
||||
"name": undefined,
|
||||
"namespaces": [],
|
||||
"tables": [
|
||||
{
|
||||
"checks": [],
|
||||
"columns": {
|
||||
"email": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "email",
|
||||
"nullable": true,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"email_verified": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": 0,
|
||||
"mappedType": "datetime",
|
||||
"name": "email_verified",
|
||||
"nullable": true,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "datetime",
|
||||
"unsigned": false,
|
||||
},
|
||||
"id": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "id",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"image": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "image",
|
||||
"nullable": true,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"name": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "name",
|
||||
"nullable": true,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
},
|
||||
"comment": undefined,
|
||||
"foreignKeys": {},
|
||||
"indexes": [
|
||||
{
|
||||
"columnNames": [
|
||||
"email",
|
||||
],
|
||||
"composite": false,
|
||||
"keyName": "user_email_unique",
|
||||
"primary": false,
|
||||
"unique": true,
|
||||
},
|
||||
{
|
||||
"columnNames": [
|
||||
"id",
|
||||
],
|
||||
"composite": false,
|
||||
"expression": undefined,
|
||||
"keyName": "primary",
|
||||
"primary": true,
|
||||
"type": undefined,
|
||||
"unique": true,
|
||||
},
|
||||
],
|
||||
"name": "user",
|
||||
"schema": undefined,
|
||||
},
|
||||
{
|
||||
"checks": [],
|
||||
"columns": {
|
||||
"expires": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": 0,
|
||||
"mappedType": "datetime",
|
||||
"name": "expires",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "datetime",
|
||||
"unsigned": false,
|
||||
},
|
||||
"id": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "id",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"session_token": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "session_token",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"user_id": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "user_id",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
},
|
||||
"comment": undefined,
|
||||
"foreignKeys": {
|
||||
"session_user_id_foreign": {
|
||||
"columnNames": [
|
||||
"user_id",
|
||||
],
|
||||
"constraintName": "session_user_id_foreign",
|
||||
"deleteRule": "cascade",
|
||||
"localTableName": "session",
|
||||
"referencedColumnNames": [
|
||||
"id",
|
||||
],
|
||||
"referencedTableName": "user",
|
||||
"updateRule": "cascade",
|
||||
},
|
||||
},
|
||||
"indexes": [
|
||||
{
|
||||
"columnNames": [
|
||||
"user_id",
|
||||
],
|
||||
"composite": false,
|
||||
"keyName": "session_user_id_index",
|
||||
"primary": false,
|
||||
"unique": false,
|
||||
},
|
||||
{
|
||||
"columnNames": [
|
||||
"session_token",
|
||||
],
|
||||
"composite": false,
|
||||
"keyName": "session_session_token_unique",
|
||||
"primary": false,
|
||||
"unique": true,
|
||||
},
|
||||
{
|
||||
"columnNames": [
|
||||
"id",
|
||||
],
|
||||
"composite": false,
|
||||
"expression": undefined,
|
||||
"keyName": "primary",
|
||||
"primary": true,
|
||||
"type": undefined,
|
||||
"unique": true,
|
||||
},
|
||||
],
|
||||
"name": "session",
|
||||
"schema": undefined,
|
||||
},
|
||||
{
|
||||
"checks": [],
|
||||
"columns": {
|
||||
"access_token": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "access_token",
|
||||
"nullable": true,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"expires_at": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "integer",
|
||||
"name": "expires_at",
|
||||
"nullable": true,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "integer",
|
||||
"unsigned": false,
|
||||
},
|
||||
"id": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "id",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"id_token": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "id_token",
|
||||
"nullable": true,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"provider": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "provider",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"provider_account_id": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "provider_account_id",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"refresh_token": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "refresh_token",
|
||||
"nullable": true,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"scope": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "scope",
|
||||
"nullable": true,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"session_state": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "session_state",
|
||||
"nullable": true,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"token_type": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "token_type",
|
||||
"nullable": true,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"type": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "type",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"user_id": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "user_id",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
},
|
||||
"comment": undefined,
|
||||
"foreignKeys": {
|
||||
"account_user_id_foreign": {
|
||||
"columnNames": [
|
||||
"user_id",
|
||||
],
|
||||
"constraintName": "account_user_id_foreign",
|
||||
"deleteRule": "cascade",
|
||||
"localTableName": "account",
|
||||
"referencedColumnNames": [
|
||||
"id",
|
||||
],
|
||||
"referencedTableName": "user",
|
||||
"updateRule": "cascade",
|
||||
},
|
||||
},
|
||||
"indexes": [
|
||||
{
|
||||
"columnNames": [
|
||||
"user_id",
|
||||
],
|
||||
"composite": false,
|
||||
"keyName": "account_user_id_index",
|
||||
"primary": false,
|
||||
"unique": false,
|
||||
},
|
||||
{
|
||||
"columnNames": [
|
||||
"provider",
|
||||
"provider_account_id",
|
||||
],
|
||||
"composite": true,
|
||||
"expression": undefined,
|
||||
"keyName": "account_provider_provider_account_id_unique",
|
||||
"primary": false,
|
||||
"type": undefined,
|
||||
"unique": true,
|
||||
},
|
||||
{
|
||||
"columnNames": [
|
||||
"id",
|
||||
],
|
||||
"composite": false,
|
||||
"expression": undefined,
|
||||
"keyName": "primary",
|
||||
"primary": true,
|
||||
"type": undefined,
|
||||
"unique": true,
|
||||
},
|
||||
],
|
||||
"name": "account",
|
||||
"schema": undefined,
|
||||
},
|
||||
{
|
||||
"checks": [],
|
||||
"columns": {
|
||||
"expires": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": 0,
|
||||
"mappedType": "datetime",
|
||||
"name": "expires",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "datetime",
|
||||
"unsigned": false,
|
||||
},
|
||||
"identifier": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "identifier",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
"token": {
|
||||
"autoincrement": false,
|
||||
"comment": undefined,
|
||||
"default": undefined,
|
||||
"enumItems": undefined,
|
||||
"extra": undefined,
|
||||
"length": undefined,
|
||||
"mappedType": "text",
|
||||
"name": "token",
|
||||
"nullable": false,
|
||||
"precision": undefined,
|
||||
"primary": false,
|
||||
"scale": undefined,
|
||||
"type": "text",
|
||||
"unsigned": false,
|
||||
},
|
||||
},
|
||||
"comment": undefined,
|
||||
"foreignKeys": {},
|
||||
"indexes": [
|
||||
{
|
||||
"columnNames": [
|
||||
"token",
|
||||
"identifier",
|
||||
],
|
||||
"composite": true,
|
||||
"expression": undefined,
|
||||
"keyName": "verification_token_token_identifier_unique",
|
||||
"primary": false,
|
||||
"type": undefined,
|
||||
"unique": true,
|
||||
},
|
||||
{
|
||||
"columnNames": [
|
||||
"token",
|
||||
],
|
||||
"composite": false,
|
||||
"expression": undefined,
|
||||
"keyName": "primary",
|
||||
"primary": true,
|
||||
"type": undefined,
|
||||
"unique": true,
|
||||
},
|
||||
],
|
||||
"name": "verification_token",
|
||||
"schema": undefined,
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
@@ -1,69 +1,10 @@
|
||||
import { Options, types } from "@mikro-orm/core"
|
||||
import type { Options } from "@mikro-orm/core"
|
||||
import type { SqliteDriver } from "@mikro-orm/sqlite"
|
||||
|
||||
import { MikroORM, wrap } from "@mikro-orm/core"
|
||||
import { runBasicTests } from "@next-auth/adapter-test"
|
||||
import { MikroOrmAdapter, defaultEntities } from "../src"
|
||||
import {
|
||||
Cascade,
|
||||
Collection,
|
||||
Entity,
|
||||
OneToMany,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
Unique,
|
||||
} from "@mikro-orm/core"
|
||||
import { randomUUID } from "@next-auth/adapter-test"
|
||||
|
||||
@Entity()
|
||||
export class User implements defaultEntities.User {
|
||||
@PrimaryKey()
|
||||
@Property({ type: types.string })
|
||||
id: string = randomUUID()
|
||||
|
||||
@Property({ type: types.string, nullable: true })
|
||||
name?: string
|
||||
|
||||
@Property({ type: types.string, nullable: true })
|
||||
@Unique()
|
||||
email?: string
|
||||
|
||||
@Property({ type: 'Date', nullable: true })
|
||||
emailVerified: Date | null = null
|
||||
|
||||
@Property({ type: types.string, nullable: true })
|
||||
image?: string
|
||||
|
||||
@OneToMany({
|
||||
entity: 'Session',
|
||||
mappedBy: (session: defaultEntities.Session) => session.user,
|
||||
hidden: true,
|
||||
orphanRemoval: true,
|
||||
cascade: [Cascade.ALL],
|
||||
})
|
||||
sessions = new Collection<defaultEntities.Session>(this)
|
||||
|
||||
@OneToMany({
|
||||
entity: 'Account',
|
||||
mappedBy: (account: defaultEntities.Account) => account.user,
|
||||
hidden: true,
|
||||
orphanRemoval: true,
|
||||
cascade: [Cascade.ALL],
|
||||
})
|
||||
accounts = new Collection<defaultEntities.Account>(this)
|
||||
|
||||
@Property({ type: types.string, hidden: true })
|
||||
role = "ADMIN"
|
||||
}
|
||||
|
||||
@Entity()
|
||||
export class VeryImportantEntity {
|
||||
@PrimaryKey()
|
||||
@Property({ type: types.string })
|
||||
id: string = randomUUID()
|
||||
|
||||
@Property({ type: types.boolean })
|
||||
important = true
|
||||
}
|
||||
import { User, VeryImportantEntity } from "./testEntities"
|
||||
|
||||
let _init: MikroORM
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
import { MikroORM, Options } from "@mikro-orm/core";
|
||||
import { SqliteDriver } from "@mikro-orm/sqlite";
|
||||
import { defaultEntities } from "../src";
|
||||
|
||||
const config: Options<SqliteDriver> = {
|
||||
dbName: "./db.sqlite",
|
||||
type: "sqlite",
|
||||
entities: [
|
||||
defaultEntities.User,
|
||||
defaultEntities.Account,
|
||||
defaultEntities.Session,
|
||||
defaultEntities.VerificationToken,
|
||||
],
|
||||
}
|
||||
|
||||
it("run migrations", async () => {
|
||||
const orm = await MikroORM.init(config)
|
||||
await orm.getSchemaGenerator().dropSchema()
|
||||
|
||||
const createSchemaSQL = await orm.getSchemaGenerator().getCreateSchemaSQL()
|
||||
expect(createSchemaSQL).toMatchSnapshot('createSchemaSQL')
|
||||
|
||||
const targetSchema = await orm.getSchemaGenerator().getTargetSchema()
|
||||
expect(targetSchema).toMatchSnapshot('targetSchema')
|
||||
|
||||
await orm.getSchemaGenerator().dropSchema()
|
||||
await orm.close().catch(() => null)
|
||||
})
|
||||
61
packages/adapter-mikro-orm/tests/testEntities.ts
Normal file
61
packages/adapter-mikro-orm/tests/testEntities.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import {
|
||||
Cascade,
|
||||
Collection,
|
||||
Entity,
|
||||
OneToMany,
|
||||
PrimaryKey,
|
||||
Property,
|
||||
Unique,
|
||||
} from "@mikro-orm/core"
|
||||
import { randomUUID } from "@next-auth/adapter-test"
|
||||
import type { defaultEntities } from "../src"
|
||||
import { Account, Session } from "../src/entities"
|
||||
|
||||
@Entity()
|
||||
export class User implements defaultEntities.User {
|
||||
@PrimaryKey()
|
||||
id: string = randomUUID()
|
||||
|
||||
@Property({ nullable: true })
|
||||
name?: string
|
||||
|
||||
@Property({ nullable: true })
|
||||
@Unique()
|
||||
email?: string
|
||||
|
||||
@Property({ type: "Date", nullable: true })
|
||||
emailVerified: Date | null = null
|
||||
|
||||
@Property({ nullable: true })
|
||||
image?: string
|
||||
|
||||
@OneToMany({
|
||||
entity: () => Session,
|
||||
mappedBy: (session) => session.user,
|
||||
hidden: true,
|
||||
orphanRemoval: true,
|
||||
cascade: [Cascade.ALL],
|
||||
})
|
||||
sessions = new Collection<Session>(this)
|
||||
|
||||
@OneToMany({
|
||||
entity: () => Account,
|
||||
mappedBy: (account) => account.user,
|
||||
hidden: true,
|
||||
orphanRemoval: true,
|
||||
cascade: [Cascade.ALL],
|
||||
})
|
||||
accounts = new Collection<Account>(this)
|
||||
|
||||
@Property({ hidden: true })
|
||||
role = "ADMIN"
|
||||
}
|
||||
|
||||
@Entity()
|
||||
export class VeryImportantEntity {
|
||||
@PrimaryKey()
|
||||
id: string = randomUUID()
|
||||
|
||||
@Property()
|
||||
important = true
|
||||
}
|
||||
@@ -5,4 +5,4 @@
|
||||
"./*.js",
|
||||
"./*.d.ts",
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,5 @@
|
||||
"outDir": "dist",
|
||||
"stripInternal": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["dist", "test", "node_modules"]
|
||||
"exclude": ["tests", "dist", "jest.config.js"]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@next-auth/mongodb-adapter",
|
||||
"version": "1.1.0",
|
||||
"version": "1.0.4",
|
||||
"description": "mongoDB adapter for next-auth.",
|
||||
"homepage": "https://next-auth.js.org",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "next-auth",
|
||||
"version": "4.11.0",
|
||||
"version": "4.10.3",
|
||||
"description": "Authentication for Next.js",
|
||||
"homepage": "https://next-auth.js.org",
|
||||
"repository": "https://github.com/nextauthjs/next-auth.git",
|
||||
@@ -69,7 +69,7 @@
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.16.3",
|
||||
"@panva/hkdf": "^1.0.1",
|
||||
"cookie": "^0.5.0",
|
||||
"cookie": "^0.4.1",
|
||||
"jose": "^4.3.7",
|
||||
"oauth": "^0.9.15",
|
||||
"openid-client": "^5.1.0",
|
||||
@@ -78,7 +78,6 @@
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"next": "12.2.5",
|
||||
"nodemailer": "^6.6.5",
|
||||
"react": "^17.0.2 || ^18",
|
||||
"react-dom": "^17.0.2 || ^18"
|
||||
@@ -119,7 +118,7 @@
|
||||
"jest-environment-jsdom": "^28.1.1",
|
||||
"jest-watch-typeahead": "^1.1.0",
|
||||
"msw": "^0.42.3",
|
||||
"next": "12.2.5",
|
||||
"next": "12.2.0",
|
||||
"postcss": "^8.4.14",
|
||||
"postcss-cli": "^9.1.0",
|
||||
"postcss-nested": "^5.0.6",
|
||||
@@ -130,4 +129,4 @@
|
||||
"engines": {
|
||||
"node": "^12.19.0 || ^14.15.0 || ^16.13.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,13 +106,12 @@ async function handleMiddleware(
|
||||
const signInPage = options?.pages?.signIn ?? "/api/auth/signin"
|
||||
const errorPage = options?.pages?.error ?? "/api/auth/error"
|
||||
const basePath = parseUrl(process.env.NEXTAUTH_URL).path
|
||||
const publicPaths = ["/_next", "/favicon.ico"]
|
||||
const publicPaths = [signInPage, errorPage, "/_next", "/favicon.ico"]
|
||||
|
||||
// Avoid infinite redirects/invalid response
|
||||
// on paths that never require authentication
|
||||
if (
|
||||
pathname.startsWith(basePath) ||
|
||||
[signInPage, errorPage].includes(pathname) ||
|
||||
publicPaths.some((p) => pathname.startsWith(p))
|
||||
) {
|
||||
return
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import { NextMiddleware } from "next/server"
|
||||
import { NextAuthMiddlewareOptions, withAuth } from "../next/middleware"
|
||||
|
||||
it("should not match pages as public paths", async () => {
|
||||
const options: NextAuthMiddlewareOptions = {
|
||||
pages: {
|
||||
signIn: "/",
|
||||
error: "/"
|
||||
},
|
||||
secret: "secret"
|
||||
}
|
||||
|
||||
const nextUrl: any = {
|
||||
pathname: "/protected/pathA",
|
||||
search: "",
|
||||
origin: "http://127.0.0.1"
|
||||
}
|
||||
const req: any = { nextUrl, headers: { authorization: "" } }
|
||||
|
||||
const handleMiddleware = withAuth(options) as NextMiddleware
|
||||
const res = await handleMiddleware(req, null)
|
||||
expect(res).toBeDefined()
|
||||
expect(res.status).toBe(307)
|
||||
})
|
||||
|
||||
it("should not redirect on public paths", async () => {
|
||||
const options: NextAuthMiddlewareOptions = {
|
||||
secret: "secret"
|
||||
}
|
||||
const nextUrl: any = {
|
||||
pathname: "/_next/foo",
|
||||
search: "",
|
||||
origin: "http://127.0.0.1"
|
||||
}
|
||||
const req: any = { nextUrl, headers: { authorization: "" } }
|
||||
|
||||
const handleMiddleware = withAuth(options) as NextMiddleware
|
||||
const res = await handleMiddleware(req, null)
|
||||
expect(res).toBeUndefined()
|
||||
})
|
||||
1236
pnpm-lock.yaml
generated
1236
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user