mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
Compare commits
21 Commits
ndom91/doc
...
feat/drizz
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b72eabb15d | ||
|
|
371f7bd4a1 | ||
|
|
35f71bbcc8 | ||
|
|
97b1202ecb | ||
|
|
8423a05e95 | ||
|
|
6c07331cc5 | ||
|
|
c8ef94b2be | ||
|
|
75a59fbd92 | ||
|
|
3dd47b0735 | ||
|
|
4dc1d421f8 | ||
|
|
99ca67f1cf | ||
|
|
a087df8494 | ||
|
|
1aa4994de6 | ||
|
|
88023f69b9 | ||
|
|
b02057a72d | ||
|
|
400da8c766 | ||
|
|
b48104801b | ||
|
|
ccbbc800d2 | ||
|
|
d7888263ca | ||
|
|
47d3151410 | ||
|
|
7d264860ab |
@@ -1,70 +0,0 @@
|
||||
.eslintrc.js
|
||||
.cache-loader
|
||||
.DS_Store
|
||||
.pnpm-debug.log
|
||||
.turbo
|
||||
.vscode/generated*
|
||||
/_work
|
||||
/actions-runner
|
||||
node_modules
|
||||
patches
|
||||
pnpm-lock.yaml
|
||||
.github/actions/issue-validator/index.mjs
|
||||
*.cjs
|
||||
*.js
|
||||
*.d.ts
|
||||
*.d.ts.map
|
||||
|
||||
.svelte-kit
|
||||
.next
|
||||
.nuxt
|
||||
|
||||
# --------------- Docs ---------------
|
||||
|
||||
.docusaurus
|
||||
build
|
||||
docs/docs/reference/core
|
||||
docs/docs/reference/sveltekit
|
||||
static
|
||||
|
||||
# --------------- Packages ---------------
|
||||
|
||||
coverage
|
||||
dist
|
||||
|
||||
# @auth/core
|
||||
packages/core/src/providers/oauth-types.ts
|
||||
packages/core/src/lib/pages/styles.ts
|
||||
|
||||
# @auth/sveltekit
|
||||
packages/frameworks-sveltekit/package
|
||||
packages/frameworks-sveltekit/vite.config.{js,ts}.timestamp-*
|
||||
|
||||
# next-auth
|
||||
packages/next-auth/src/providers/oauth-types.ts
|
||||
packages/next-auth/css/index.css
|
||||
|
||||
|
||||
# Adapters
|
||||
.branches
|
||||
db.sqlite
|
||||
dev.db
|
||||
dynamodblocal-bin
|
||||
firebase-debug.log
|
||||
firestore-debug.log
|
||||
migrations
|
||||
test.schema.gql
|
||||
|
||||
# --------------- Apps ---------------
|
||||
|
||||
|
||||
# Examples should have their own Prettier config since they are templates too
|
||||
apps/example-sveltekit
|
||||
|
||||
# Development app
|
||||
apps
|
||||
|
||||
|
||||
# --------------- Tests ---------------
|
||||
# TODO: these should be linted
|
||||
packages/**/*test*
|
||||
75
.eslintrc.js
75
.eslintrc.js
@@ -1,75 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
/** @type {import("eslint").ESLint.ConfigData} */
|
||||
module.exports = {
|
||||
env: { browser: true, es2022: true, node: true },
|
||||
extends: ["eslint:recommended", "prettier"],
|
||||
overrides: [
|
||||
{
|
||||
files: ["*.ts", "*.tsx"],
|
||||
parser: "@typescript-eslint/parser",
|
||||
parserOptions: {
|
||||
project: ["./packages/**/tsconfig.json", "./apps/**/tsconfig.json"],
|
||||
},
|
||||
settings: { react: { version: "18" } },
|
||||
extends: [
|
||||
"plugin:react/recommended",
|
||||
"plugin:react/jsx-runtime",
|
||||
"standard-with-typescript",
|
||||
"prettier",
|
||||
],
|
||||
rules: {
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/method-signature-style": "off",
|
||||
"@typescript-eslint/naming-convention": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
"@typescript-eslint/strict-boolean-expressions": "off",
|
||||
"react/prop-types": "off",
|
||||
"react/no-unescaped-entities": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["*.test.ts", "*.test.js"],
|
||||
extends: ["plugin:jest/recommended"],
|
||||
env: { jest: true },
|
||||
},
|
||||
{
|
||||
files: ["docs/**"],
|
||||
plugins: ["@docusaurus"],
|
||||
extends: ["plugin:@docusaurus/recommended"],
|
||||
},
|
||||
{
|
||||
// TODO: Expand to all packages
|
||||
files: ["packages/{core,sveltekit}/*.ts"],
|
||||
plugins: ["jsdoc"],
|
||||
extends: ["plugin:jsdoc/recommended"],
|
||||
rules: {
|
||||
"jsdoc/require-param": "off",
|
||||
"jsdoc/require-returns": "off",
|
||||
"jsdoc/require-jsdoc": [
|
||||
"warn",
|
||||
{ publicOnly: true, enableFixer: false },
|
||||
],
|
||||
"jsdoc/no-multi-asterisks": ["warn", { allowWhitespace: true }],
|
||||
"jsdoc/tag-lines": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ["packages/frameworks-sveltekit"],
|
||||
plugins: ["svelte3"],
|
||||
overrides: [{ files: ["*.svelte"], processor: "svelte3/svelte3" }],
|
||||
settings: {
|
||||
"svelte3/typescript": () => require("typescript"),
|
||||
},
|
||||
parserOptions: { sourceType: "module", ecmaVersion: 2020 },
|
||||
env: { browser: true, es2017: true, node: true },
|
||||
},
|
||||
],
|
||||
parserOptions: {
|
||||
sourceType: "module",
|
||||
ecmaVersion: "latest",
|
||||
ecmaFeatures: { jsx: true },
|
||||
},
|
||||
root: true,
|
||||
}
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -63,6 +63,7 @@ packages/adapter-prisma/prisma/dev.db
|
||||
packages/adapter-prisma/prisma/migrations
|
||||
db.sqlite
|
||||
packages/adapter-supabase/supabase/.branches
|
||||
packages/adapter-drizzle/drizzle
|
||||
|
||||
# Tests
|
||||
coverage
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
// @ts-check
|
||||
|
||||
/** @type {import("prettier").Config} */
|
||||
module.exports = {
|
||||
semi: false,
|
||||
singleQuote: false,
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
"apps/dev/nextjs/pages/api/auth/[...nextauth].ts",
|
||||
"docs/{sidebars,docusaurus.config}.js",
|
||||
],
|
||||
options: { printWidth: 150 },
|
||||
},
|
||||
{
|
||||
files: ["**/*package.json"],
|
||||
options: {
|
||||
trailingComma: "none",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -52,6 +52,10 @@ TWITTER_SECRET=
|
||||
WIKIMEDIA_ID=
|
||||
WIKIMEDIA_SECRET=
|
||||
|
||||
# Yandex OAuth. new app -> https://oauth.yandex.com/client/new/id
|
||||
YANDEX_ID=
|
||||
YANDEX_SECRET=
|
||||
|
||||
# Example configuration for a Gmail account (will need SMTP enabled)
|
||||
EMAIL_SERVER=smtps://user@gmail.com:password@smtp.gmail.com:465
|
||||
EMAIL_FROM=user@gmail.com
|
||||
|
||||
@@ -34,6 +34,7 @@ import Spotify from "@auth/core/providers/spotify"
|
||||
import Trakt from "@auth/core/providers/trakt"
|
||||
import Twitch from "@auth/core/providers/twitch"
|
||||
import Twitter from "@auth/core/providers/twitter"
|
||||
import Yandex from "@auth/core/providers/yandex"
|
||||
import Vk from "@auth/core/providers/vk"
|
||||
import Wikimedia from "@auth/core/providers/wikimedia"
|
||||
import WorkOS from "@auth/core/providers/workos"
|
||||
@@ -120,6 +121,7 @@ export const authConfig: AuthConfig = {
|
||||
Twitch({ clientId: process.env.TWITCH_ID, clientSecret: process.env.TWITCH_SECRET }),
|
||||
Twitter({ clientId: process.env.TWITTER_ID, clientSecret: process.env.TWITTER_SECRET }),
|
||||
// TwitterLegacy({ clientId: process.env.TWITTER_LEGACY_ID, clientSecret: process.env.TWITTER_LEGACY_SECRET }),
|
||||
Yandex({ clientId: process.env.YANDEX_ID, clientSecret: process.env.YANDEX_SECRET }),
|
||||
Vk({ clientId: process.env.VK_ID, clientSecret: process.env.VK_SECRET }),
|
||||
Wikimedia({ clientId: process.env.WIKIMEDIA_ID, clientSecret: process.env.WIKIMEDIA_SECRET }),
|
||||
WorkOS({ clientId: process.env.WORKOS_ID, clientSecret: process.env.WORKOS_SECRET }),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { unstable_getServerSession } from "next-auth/next"
|
||||
import { getServerSession } from "next-auth/next"
|
||||
import { authOptions } from "./api/auth/[...nextauth]"
|
||||
import Layout from "../components/layout"
|
||||
|
||||
@@ -38,7 +38,7 @@ export default function ServerSidePage() {
|
||||
export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
return {
|
||||
props: {
|
||||
session: await unstable_getServerSession(
|
||||
session: await getServerSession(
|
||||
context.req,
|
||||
context.res,
|
||||
authOptions
|
||||
|
||||
@@ -46,7 +46,7 @@ export default NextAuth({
|
||||
```
|
||||
|
||||
:::note
|
||||
Check the [Credentials Provider options](/reference/providers/credentials) for further customization
|
||||
Check the [Credentials Provider options](/reference/core/providers_credentials) for further customization
|
||||
:::
|
||||
|
||||
Note that we only need to define an `authorize` method that is in charge of receiving the credentials inserted by the user and call the authorization service.
|
||||
|
||||
@@ -66,7 +66,7 @@ Nice! We're getting there. Now we need to read supply this values as the configu
|
||||
|
||||
```ts title="pages/api/auth/[...nextauth].ts"
|
||||
import NextAuth from "next-auth"
|
||||
import EmailProvider from "next-auth/providers/email"
|
||||
import Email from "next-auth/providers/email"
|
||||
|
||||
export default NextAuth({
|
||||
providers: [
|
||||
|
||||
@@ -239,7 +239,7 @@ Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.1
|
||||
|
||||
## `nodemailer`
|
||||
|
||||
Like `typeorm` and `prisma`, [`nodemailer`](https://npmjs.com/package/nodemailer) is no longer included as a dependency by default. If you are using the Email provider you must install it in your project manually, or use any other Email library in the [`sendVerificationRequest`](/reference/providers/email) callback. This reduces bundle size for those not actually using the Email provider. Remember, when using the Email provider, it is mandatory to also use a database adapter due to the fact that verification tokens need to be persisted longer term for the magic link functionality to work.
|
||||
Like `typeorm` and `prisma`, [`nodemailer`](https://npmjs.com/package/nodemailer) is no longer included as a dependency by default. If you are using the Email provider you must install it in your project manually, or use any other Email library in the [`sendVerificationRequest`](/guides/providers/email) callback. This reduces bundle size for those not actually using the Email provider. Remember, when using the Email provider, it is mandatory to also use a database adapter due to the fact that verification tokens need to be persisted longer term for the magic link functionality to work.
|
||||
|
||||
Introduced in https://github.com/nextauthjs/next-auth/releases/tag/v4.0.0-next.2
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ The functionality provided for credentials-based authentication is intentionally
|
||||
|
||||
The **Credentials Provider** comes with a set of default options:
|
||||
|
||||
- [Credentials Provider options](/reference/providers/credentials)
|
||||
- [Credentials Provider options](/reference/core/providers_credentials)
|
||||
|
||||
You can override any of the options to suit your own use case.
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ The Email Provider can be used with both JSON Web Tokens and database sessions,
|
||||
|
||||
The **Email Provider** comes with a set of default options:
|
||||
|
||||
- [Email Provider options](/reference/providers/email)
|
||||
- [Email Provider options](/guides/providers/email)
|
||||
|
||||
You can override any of the options to suit your own use case.
|
||||
|
||||
|
||||
@@ -9,6 +9,10 @@ Using a Auth.js / NextAuth.js adapter you can connect to any database service or
|
||||
<img src="/img/adapters/dgraph.png" width="30" />
|
||||
<h4 class="adapter-card__title">Dgraph Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/drizzle" class="adapter-card">
|
||||
<img src="/img/adapters/drizzle-orm.png" width="30" />
|
||||
<h4 class="adapter-card__title">Drizzle ORM Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/dynamodb" class="adapter-card">
|
||||
<img src="/img/adapters/dynamodb.png" width="30" />
|
||||
<h4 class="adapter-card__title">DynamoDB Adapter</h4>
|
||||
@@ -52,7 +56,7 @@ Using a Auth.js / NextAuth.js adapter you can connect to any database service or
|
||||
<a href="/reference/adapter/typeorm" class="adapter-card">
|
||||
<img src="/img/adapters/typeorm.png" width="30" />
|
||||
<h4 class="adapter-card__title">TypeORM Adapter</h4>
|
||||
</a>
|
||||
</a>
|
||||
<a href="/reference/adapter/upstash-redis" class="adapter-card">
|
||||
<img src="/img/adapters/upstash-redis.svg" width="30" />
|
||||
<h4 class="adapter-card__title">Upstash Adapter</h4>
|
||||
@@ -133,7 +137,7 @@ If a user first signs in with OAuth then their email address is automatically po
|
||||
This provides a way to contact users and for users to maintain access to their account and sign in using email in the event they are unable to sign in with the OAuth provider in future (if the [Email Provider](/getting-started/email-tutorial) is configured).
|
||||
:::
|
||||
|
||||
User creation in the database is automatic, and happens when the user is logging in for the first time with a provider. The default data saved is `id`, `name`, `email` and `image`. You can add more profile data by returning extra fields in your [OAuth provider's `profile()`](/reference/providers/oauth) callback.
|
||||
User creation in the database is automatic, and happens when the user is logging in for the first time with a provider. The default data saved is `id`, `name`, `email` and `image`. You can add more profile data by returning extra fields in your [OAuth provider](/guides/providers/custom-provider)'s [`profile()`](/reference/core/providers#profile) callback.
|
||||
|
||||
### Account
|
||||
|
||||
@@ -174,7 +178,7 @@ A single User can have multiple open Verification Tokens (e.g. to sign in to dif
|
||||
It has been designed to be extendable for other verification purposes in the future (e.g. 2FA / short codes).
|
||||
|
||||
:::note
|
||||
Auth.js makes sure that every token is usable only once, and by default has a short (1 day, can be configured by [`maxAge`](/reference/providers/email)) lifetime. If your user did not manage to finish the sign-in flow in time, they will have to start the sign-in process again.
|
||||
Auth.js makes sure that every token is usable only once, and by default has a short (1 day, can be configured by [`maxAge`](/guides/providers/email)) lifetime. If your user did not manage to finish the sign-in flow in time, they will have to start the sign-in process again.
|
||||
:::
|
||||
|
||||
:::tip
|
||||
@@ -188,4 +192,4 @@ Auth.js / NextAuth.js uses `camelCase` for its own database rows, while respecti
|
||||
|
||||
## TypeScript
|
||||
|
||||
Check out the [`@auth/core/adapters` API Reference](/reference/core/adapters) documentation.
|
||||
Check out the [`@auth/core/adapters` API Reference](/reference/core/adapters) documentation.
|
||||
|
||||
@@ -262,6 +262,7 @@ const docusaurusConfig = {
|
||||
},
|
||||
],
|
||||
typedocAdapter("Dgraph"),
|
||||
typedocAdapter("Drizzle ORM"),
|
||||
typedocAdapter("DynamoDB"),
|
||||
typedocAdapter("Fauna"),
|
||||
typedocAdapter("Firebase"),
|
||||
|
||||
@@ -53,6 +53,7 @@ module.exports = {
|
||||
items: [
|
||||
{ type: "doc", id: "reference/adapter/dgraph/index" },
|
||||
{ type: "doc", id: "reference/adapter/dynamodb/index" },
|
||||
{ type: "doc", id: "reference/adapter/drizzle/index" },
|
||||
{ type: "doc", id: "reference/adapter/fauna/index" },
|
||||
{ type: "doc", id: "reference/adapter/firebase/index" },
|
||||
{ type: "doc", id: "reference/adapter/mikro-orm/index" },
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
transition: 0.2s background-color ease-in-out;
|
||||
}
|
||||
|
||||
html[data-theme="dark"] .adapter-card {
|
||||
color: #f5f5f5;
|
||||
}
|
||||
|
||||
.adapter-card:hover {
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
|
||||
@@ -128,16 +128,6 @@ export default function Home() {
|
||||
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
||||
</div>
|
||||
<div className={styles.buttons}>
|
||||
<Link
|
||||
className={classnames(
|
||||
"button button--primary button--lg rounded-pill button-start",
|
||||
styles.button,
|
||||
styles.buttonStart
|
||||
)}
|
||||
to={useBaseUrl("/getting-started/introduction")}
|
||||
>
|
||||
Get Started
|
||||
</Link>
|
||||
<a
|
||||
className={classnames(
|
||||
"button button--outline button--secondary button--lg rounded-pill",
|
||||
@@ -145,7 +135,7 @@ export default function Home() {
|
||||
)}
|
||||
href="https://next-auth-example.vercel.app"
|
||||
>
|
||||
<img src="/img/framework-nextjs-white.svg" height="48" width="48" />
|
||||
Next.js Demo
|
||||
</a>
|
||||
<a
|
||||
className={classnames(
|
||||
@@ -154,7 +144,7 @@ export default function Home() {
|
||||
)}
|
||||
href="https://sveltekit-auth-example.vercel.app"
|
||||
>
|
||||
<img src="/img/framework-sveltekit.svg" height="48" width="48" />
|
||||
SvelteKit Demo
|
||||
</a>
|
||||
<a
|
||||
className={classnames(
|
||||
@@ -163,8 +153,17 @@ export default function Home() {
|
||||
)}
|
||||
href="https://auth-solid.vercel.app"
|
||||
>
|
||||
<img src="/img/framework-solidstart.svg" height="48" width="48" />
|
||||
SolidStart Demo
|
||||
</a>
|
||||
<Link
|
||||
className={classnames(
|
||||
"button button--primary button--lg rounded-pill",
|
||||
styles.button
|
||||
)}
|
||||
to={useBaseUrl("/getting-started/introduction")}
|
||||
>
|
||||
Get Started
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="hero-marquee">
|
||||
|
||||
@@ -34,31 +34,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
.frameworkWrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 4rem 1rem 2rem 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 4rem 1rem 0 1rem;
|
||||
flex-wrap: wrap;
|
||||
padding: 2rem 0;
|
||||
gap: 1rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
|
||||
.buttonStart {
|
||||
margin: 0 2rem;
|
||||
color: red;
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
|
||||
.features {
|
||||
|
||||
BIN
docs/static/img/adapters/drizzle-orm.png
vendored
Normal file
BIN
docs/static/img/adapters/drizzle-orm.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
1
docs/static/img/framework-nextjs-white.svg
vendored
1
docs/static/img/framework-nextjs-white.svg
vendored
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" aria-label="Next.js logomark" class="next-mark_root__wLeec" data-theme="dark" height="80" role="img" viewBox="0 0 180 180" width="80"><mask height="180" id="mask0_408_134" maskUnits="userSpaceOnUse" style="mask-type:alpha" width="180" x="0" y="0"><circle cx="90" cy="90" fill="black" r="90"></circle></mask><g mask="url(#mask0_408_134)"><circle cx="90" cy="90" data-circle="true" fill="black" r="90" stroke="white" stroke-width="6px"></circle><path d="M149.508 157.52L69.142 54H54V125.97H66.1136V69.3836L139.999 164.845C143.333 162.614 146.509 160.165 149.508 157.52Z" fill="url(#paint0_linear_408_134)"></path><rect fill="url(#paint1_linear_408_134)" height="72" width="12" x="115" y="54"></rect></g><defs><linearGradient gradientUnits="userSpaceOnUse" id="paint0_linear_408_134" x1="109" x2="144.5" y1="116.5" y2="160.5"><stop stop-color="white"></stop><stop offset="1" stop-color="white" stop-opacity="0"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="paint1_linear_408_134" x1="121" x2="120.799" y1="54" y2="106.875"><stop stop-color="white"></stop><stop offset="1" stop-color="white" stop-opacity="0"></stop></linearGradient></defs></svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
1
docs/static/img/framework-solidstart.svg
vendored
1
docs/static/img/framework-solidstart.svg
vendored
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 166 155.3"><defs><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="27.5" y1="3" x2="152" y2="63.5"><stop offset=".1" stop-color="#76b3e1"/><stop offset=".3" stop-color="#dcf2fd"/><stop offset="1" stop-color="#76b3e1"/></linearGradient><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="95.8" y1="32.6" x2="74" y2="105.2"><stop offset="0" stop-color="#76b3e1"/><stop offset=".5" stop-color="#4377bb"/><stop offset="1" stop-color="#1f3b77"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="18.4" y1="64.2" x2="144.3" y2="149.8"><stop offset="0" stop-color="#315aa9"/><stop offset=".5" stop-color="#518ac8"/><stop offset="1" stop-color="#315aa9"/></linearGradient><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="75.2" y1="74.5" x2="24.4" y2="260.8"><stop offset="0" stop-color="#4377bb"/><stop offset=".5" stop-color="#1a336b"/><stop offset="1" stop-color="#1a336b"/></linearGradient></defs><path d="M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z" fill="#76b3e1"/><path d="M163 35S110-4 69 5l-3 1c-6 2-11 5-14 9l-2 3-15 26 26 5c11 7 25 10 38 7l46 9 18-30z" opacity=".3" fill="url(#a)"/><path d="M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z" fill="#518ac8"/><path d="M52 35l-4 1c-17 5-22 21-13 35 10 13 31 20 48 15l62-21S92 26 52 35z" opacity=".3" fill="url(#b)"/><path d="M134 80a45 45 0 00-48-15L24 85 4 120l112 19 20-36c4-7 3-15-2-23z" fill="url(#c)"/><path d="M114 115a45 45 0 00-48-15L4 120s53 40 94 30l3-1c17-5 23-21 13-34z" fill="url(#d)"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB |
1
docs/static/img/framework-sveltekit.svg
vendored
1
docs/static/img/framework-sveltekit.svg
vendored
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="107" height="128" viewBox="0 0 107 128"><title>svelte-logo</title><path d="M94.1566,22.8189c-10.4-14.8851-30.94-19.2971-45.7914-9.8348L22.2825,29.6078A29.9234,29.9234,0,0,0,8.7639,49.6506a31.5136,31.5136,0,0,0,3.1076,20.2318A30.0061,30.0061,0,0,0,7.3953,81.0653a31.8886,31.8886,0,0,0,5.4473,24.1157c10.4022,14.8865,30.9423,19.2966,45.7914,9.8348L84.7167,98.3921A29.9177,29.9177,0,0,0,98.2353,78.3493,31.5263,31.5263,0,0,0,95.13,58.117a30,30,0,0,0,4.4743-11.1824,31.88,31.88,0,0,0-5.4473-24.1157" style="fill:#ff3e00"/><path d="M45.8171,106.5815A20.7182,20.7182,0,0,1,23.58,98.3389a19.1739,19.1739,0,0,1-3.2766-14.5025,18.1886,18.1886,0,0,1,.6233-2.4357l.4912-1.4978,1.3363.9815a33.6443,33.6443,0,0,0,10.203,5.0978l.9694.2941-.0893.9675a5.8474,5.8474,0,0,0,1.052,3.8781,6.2389,6.2389,0,0,0,6.6952,2.485,5.7449,5.7449,0,0,0,1.6021-.7041L69.27,76.281a5.4306,5.4306,0,0,0,2.4506-3.631,5.7948,5.7948,0,0,0-.9875-4.3712,6.2436,6.2436,0,0,0-6.6978-2.4864,5.7427,5.7427,0,0,0-1.6.7036l-9.9532,6.3449a19.0329,19.0329,0,0,1-5.2965,2.3259,20.7181,20.7181,0,0,1-22.2368-8.2427,19.1725,19.1725,0,0,1-3.2766-14.5024,17.9885,17.9885,0,0,1,8.13-12.0513L55.8833,23.7472a19.0038,19.0038,0,0,1,5.3-2.3287A20.7182,20.7182,0,0,1,83.42,29.6611a19.1739,19.1739,0,0,1,3.2766,14.5025,18.4,18.4,0,0,1-.6233,2.4357l-.4912,1.4978-1.3356-.98a33.6175,33.6175,0,0,0-10.2037-5.1l-.9694-.2942.0893-.9675a5.8588,5.8588,0,0,0-1.052-3.878,6.2389,6.2389,0,0,0-6.6952-2.485,5.7449,5.7449,0,0,0-1.6021.7041L37.73,51.719a5.4218,5.4218,0,0,0-2.4487,3.63,5.7862,5.7862,0,0,0,.9856,4.3717,6.2437,6.2437,0,0,0,6.6978,2.4864,5.7652,5.7652,0,0,0,1.602-.7041l9.9519-6.3425a18.978,18.978,0,0,1,5.2959-2.3278,20.7181,20.7181,0,0,1,22.2368,8.2427,19.1725,19.1725,0,0,1,3.2766,14.5024,17.9977,17.9977,0,0,1-8.13,12.0532L51.1167,104.2528a19.0038,19.0038,0,0,1-5.3,2.3287" style="fill:#fff"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.8 KiB |
6
docs/static/img/providers/reddit.svg
vendored
Normal file
6
docs/static/img/providers/reddit.svg
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" height="32" width="32">
|
||||
<g>
|
||||
<circle fill="#FF4500" cx="10" cy="10" r="10"/>
|
||||
<path fill="#FFF" d="M16.67,10A1.46,1.46,0,0,0,14.2,9a7.12,7.12,0,0,0-3.85-1.23L11,4.65,13.14,5.1a1,1,0,1,0,.13-0.61L10.82,4a0.31,0.31,0,0,0-.37.24L9.71,7.71a7.14,7.14,0,0,0-3.9,1.23A1.46,1.46,0,1,0,4.2,11.33a2.87,2.87,0,0,0,0,.44c0,2.24,2.61,4.06,5.83,4.06s5.83-1.82,5.83-4.06a2.87,2.87,0,0,0,0-.44A1.46,1.46,0,0,0,16.67,10Zm-10,1a1,1,0,1,1,1,1A1,1,0,0,1,6.67,11Zm5.81,2.75a3.84,3.84,0,0,1-2.47.77,3.84,3.84,0,0,1-2.47-.77,0.27,0.27,0,0,1,.38-0.38A3.27,3.27,0,0,0,10,14a3.28,3.28,0,0,0,2.09-.61A0.27,0.27,0,1,1,12.48,13.79Zm-0.18-1.71a1,1,0,1,1,1-1A1,1,0,0,1,12.29,12.08Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 736 B |
1
docs/static/img/providers/yandex.svg
vendored
Normal file
1
docs/static/img/providers/yandex.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="480px" height="480px" fill-rule="nonzero"><g transform="translate(32,32) scale(0.75,0.75)"><g fill-opacity="0" fill="#ff0000" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M-42.66667,298.66667v-341.33333h341.33333v341.33333z" id="bgRectangle"></path></g><g fill="#ff0000" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><path d="M128,292.57143c-90.89029,0 -164.57143,-73.68114 -164.57143,-164.57143v0c0,-90.89029 73.68114,-164.57143 164.57143,-164.57143v0c90.89029,0 164.57143,73.68114 164.57143,164.57143v0c0,90.89029 -73.68114,164.57143 -164.57143,164.57143z" id="shape"></path></g><g fill="#ffffff" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"><g transform="scale(5.33333,5.33333)"><path d="M21.413,47.315c1.685,0.076 3.206,-0.076 4.891,0c-0.383,-4.097 0.719,-8.451 0.297,-12.544c-0.118,-1.142 0.076,-2.779 0.171,-3.924c0.102,-1.229 1.069,-3.553 1.533,-4.696c3.541,-8.731 5.77,-15.742 8.924,-24.62c-1.548,-0.029 -3.702,0.029 -5.25,0c-2.934,7.419 -5.846,15.183 -8.022,22.859c-3.659,-6.121 -5.157,-12.182 -7.055,-18.386c-0.13,-0.424 -0.284,-0.885 -0.66,-1.12c-0.247,-0.154 -0.549,-0.183 -0.839,-0.205c-1.56,-0.118 -3.126,-0.149 -4.689,-0.09c3.636,7.742 6.793,16.44 9.267,24.628c0.411,1.36 0.806,2.729 1.013,4.134c0.218,1.48 0.447,2.718 0.453,4.213c0.009,2.887 -0.044,6.865 -0.034,9.751z"></path><path d="M37.228,1.033c-1.75,-0.028 -3.5,0.028 -5.25,0c-0.238,-0.004 -0.401,0.161 -0.482,0.367c-2.823,7.142 -5.525,14.344 -7.685,21.717c-2.11,-3.802 -3.592,-7.875 -4.862,-12.033c-0.335,-1.095 -0.659,-2.193 -0.986,-3.291c-0.27,-0.904 -0.439,-2.011 -0.95,-2.815c-0.522,-0.821 -1.483,-0.798 -2.35,-0.848c-1.315,-0.076 -2.633,-0.086 -3.95,-0.041c-0.401,0.014 -0.593,0.409 -0.432,0.752c2.538,5.416 4.725,10.992 6.675,16.645c1.884,5.463 3.992,11.069 3.99,16.917c0,2.97 -0.043,5.941 -0.034,8.911c0.001,0.199 0.102,0.33 0.234,0.406c0.072,0.051 0.156,0.09 0.266,0.094c1.631,0.063 3.261,-0.063 4.891,0c0.253,0.01 0.523,-0.238 0.5,-0.5c-0.29,-3.347 0.333,-6.672 0.39,-10.014c0.026,-1.503 -0.185,-2.988 -0.088,-4.49c0.082,-1.276 0.2,-2.483 0.603,-3.701c0.908,-2.743 2.12,-5.396 3.142,-8.098c1.122,-2.965 2.185,-5.951 3.229,-8.944c1.21,-3.467 2.4,-6.941 3.629,-10.402c0.114,-0.314 -0.175,-0.627 -0.48,-0.632zM30.286,19.685c-1.051,2.814 -2.242,5.576 -3.274,8.396c-0.426,1.163 -0.695,2.274 -0.806,3.505c-0.061,0.682 -0.122,1.366 -0.138,2.051c-0.018,0.764 0.083,1.516 0.114,2.278c0.148,3.64 -0.621,7.255 -0.403,10.893c-1.288,-0.021 -2.575,0.037 -3.862,0.015c0.012,-5.353 0.438,-10.808 -0.961,-16.031c-1.566,-5.848 -3.647,-11.615 -5.86,-17.245c-1.123,-2.857 -2.331,-5.681 -3.617,-8.468c0.98,-0.018 1.96,-0.013 2.939,0.038c0.445,0.023 1.19,-0.067 1.573,0.2c0.355,0.247 0.446,0.872 0.561,1.249c0.612,2.017 1.195,4.043 1.828,6.053c1.316,4.174 2.906,8.253 5.146,12.025c0.22,0.371 0.796,0.295 0.914,-0.119c2.174,-7.647 4.961,-15.101 7.878,-22.492c1.403,0.014 2.805,-0.007 4.208,0c-2.082,5.883 -4.056,11.805 -6.24,17.652z"></path></g></g></g></svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
202
package.json
202
package.json
@@ -40,7 +40,7 @@
|
||||
"eslint-plugin-svelte3": "^4.0.0",
|
||||
"prettier": "2.8.1",
|
||||
"prettier-plugin-svelte": "^2.8.1",
|
||||
"turbo": "1.6.3",
|
||||
"turbo": "1.8.8",
|
||||
"typescript": "4.9.4"
|
||||
},
|
||||
"engines": {
|
||||
@@ -61,5 +61,205 @@
|
||||
"patchedDependencies": {
|
||||
"@balazsorban/monorepo-release@0.1.8": "patches/@balazsorban__monorepo-release@0.1.8.patch"
|
||||
}
|
||||
},
|
||||
"eslintIgnore": [
|
||||
".eslintrc.js",
|
||||
".cache-loader",
|
||||
".DS_Store",
|
||||
".pnpm-debug.log",
|
||||
".turbo",
|
||||
".vscode/generated*",
|
||||
"/_work",
|
||||
"/actions-runner",
|
||||
"node_modules",
|
||||
"patches",
|
||||
"pnpm-lock.yaml",
|
||||
".github/actions/issue-validator/index.mjs",
|
||||
"*.cjs",
|
||||
"*.js",
|
||||
"*.d.ts",
|
||||
"*.d.ts.map",
|
||||
".svelte-kit",
|
||||
".next",
|
||||
".nuxt",
|
||||
".docusaurus",
|
||||
"build",
|
||||
"docs/docs/reference/core",
|
||||
"docs/docs/reference/sveltekit",
|
||||
"static",
|
||||
"coverage",
|
||||
"dist",
|
||||
"packages/core/src/providers/oauth-types.ts",
|
||||
"packages/core/src/lib/pages/styles.ts",
|
||||
"packages/frameworks-sveltekit/package",
|
||||
"packages/frameworks-sveltekit/vite.config.{js,ts}.timestamp-*",
|
||||
"packages/next-auth/src/providers/oauth-types.ts",
|
||||
"packages/next-auth/css/index.css",
|
||||
".branches",
|
||||
"db.sqlite",
|
||||
"dev.db",
|
||||
"dynamodblocal-bin",
|
||||
"firebase-debug.log",
|
||||
"firestore-debug.log",
|
||||
"migrations",
|
||||
"test.schema.gql",
|
||||
"apps/example-sveltekit",
|
||||
"apps",
|
||||
"packages/**/*test*"
|
||||
],
|
||||
"eslintConfig": {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"prettier"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"project": [
|
||||
"./packages/**/tsconfig.json",
|
||||
"./apps/**/tsconfig.json"
|
||||
]
|
||||
},
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "18"
|
||||
}
|
||||
},
|
||||
"extends": [
|
||||
"plugin:react/recommended",
|
||||
"plugin:react/jsx-runtime",
|
||||
"standard-with-typescript",
|
||||
"prettier"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/explicit-function-return-type": "off",
|
||||
"@typescript-eslint/method-signature-style": "off",
|
||||
"@typescript-eslint/naming-convention": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
"@typescript-eslint/strict-boolean-expressions": "off",
|
||||
"react/prop-types": "off",
|
||||
"react/no-unescaped-entities": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.test.ts",
|
||||
"*.test.js"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:jest/recommended"
|
||||
],
|
||||
"env": {
|
||||
"jest": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"docs/**"
|
||||
],
|
||||
"plugins": [
|
||||
"@docusaurus"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:@docusaurus/recommended"
|
||||
]
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"packages/{core,sveltekit}/*.ts"
|
||||
],
|
||||
"plugins": [
|
||||
"jsdoc"
|
||||
],
|
||||
"extends": [
|
||||
"plugin:jsdoc/recommended"
|
||||
],
|
||||
"rules": {
|
||||
"jsdoc/require-param": "off",
|
||||
"jsdoc/require-returns": "off",
|
||||
"jsdoc/require-jsdoc": [
|
||||
"warn",
|
||||
{
|
||||
"publicOnly": true,
|
||||
"enableFixer": false
|
||||
}
|
||||
],
|
||||
"jsdoc/no-multi-asterisks": [
|
||||
"warn",
|
||||
{
|
||||
"allowWhitespace": true
|
||||
}
|
||||
],
|
||||
"jsdoc/tag-lines": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"packages/frameworks-sveltekit"
|
||||
],
|
||||
"plugins": [
|
||||
"svelte3"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.svelte"
|
||||
],
|
||||
"processor": "svelte3/svelte3"
|
||||
}
|
||||
],
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"ecmaVersion": 2020
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2017": true,
|
||||
"node": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"parserOptions": {
|
||||
"sourceType": "module",
|
||||
"ecmaVersion": "latest",
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"root": true
|
||||
},
|
||||
"prettier": {
|
||||
"semi": false,
|
||||
"singleQuote": false,
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"apps/dev/nextjs/pages/api/auth/[...nextauth].ts",
|
||||
"docs/{sidebars,docusaurus.config}.js"
|
||||
],
|
||||
"options": {
|
||||
"printWidth": 150
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"**/*package.json"
|
||||
],
|
||||
"options": {
|
||||
"trailingComma": "none"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
28
packages/adapter-drizzle/README.md
Normal file
28
packages/adapter-drizzle/README.md
Normal file
@@ -0,0 +1,28 @@
|
||||
<p align="center">
|
||||
<br/>
|
||||
<a href="https://authjs.dev" target="_blank">
|
||||
<img height="64px" src="https://authjs.dev/img/logo/logo-sm.png" />
|
||||
</a>
|
||||
<a href="https://github.com/drizzle-team/drizzle-orm" target="_blank">
|
||||
<img height="64px" src="https://authjs.dev/img/adapters/drizzle-orm.png"/>
|
||||
</a>
|
||||
<h3 align="center"><b>Drizzle ORM Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@auth/drizzle-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@auth/drizzle-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/drizzle-adapter?color=green&label=@auth/drizzle-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@auth/drizzle-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/drizzle-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
Check out the documentation at [authjs.dev](https://authjs.dev/reference/adapter/drizzle).
|
||||
57
packages/adapter-drizzle/package.json
Normal file
57
packages/adapter-drizzle/package.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "@auth/drizzle-adapter",
|
||||
"version": "0.0.1",
|
||||
"description": "Drizzle ORM adapter for Auth.js",
|
||||
"homepage": "https://authjs.dev/reference/adapter/drizzle",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
},
|
||||
"author": "Anthony Shew",
|
||||
"license": "ISC",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"keywords": [
|
||||
"auth.js",
|
||||
"next-auth",
|
||||
"next.js",
|
||||
"oauth",
|
||||
"drizzle"
|
||||
],
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rm -rf *.js *.d.ts* ./drizzle db.sqlite",
|
||||
"test:init": "pnpm clean && drizzle-kit generate:sqlite --schema=src/schema.ts --breakpoints",
|
||||
"test": "pnpm test:init && jest",
|
||||
"build": "pnpm clean && drizzle-kit generate:sqlite --schema=src/schema.ts && tsc",
|
||||
"dev": "drizzle-kit generate:sqlite --schema=src/schema.ts && tsc -w"
|
||||
},
|
||||
"files": [
|
||||
"src",
|
||||
"*.js",
|
||||
"*.d.ts*"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"drizzle-orm": "^0.23.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next-auth/adapter-test": "workspace:*",
|
||||
"@types/better-sqlite3": "^7.6.3",
|
||||
"better-sqlite3": "^8.2.0",
|
||||
"drizzle-kit": "^0.17.3",
|
||||
"drizzle-orm": "^0.23.5",
|
||||
"jest": "^27.4.3",
|
||||
"next-auth": "workspace:*"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@next-auth/adapter-test/jest"
|
||||
}
|
||||
}
|
||||
248
packages/adapter-drizzle/src/index.ts
Normal file
248
packages/adapter-drizzle/src/index.ts
Normal file
@@ -0,0 +1,248 @@
|
||||
/**
|
||||
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: 16}}>
|
||||
* <p style={{fontWeight: "normal"}}>Official <a href="https://github.com/drizzle-team/drizzle-orm">Drizzle ORM</a> adapter for Auth.js / NextAuth.js.</p>
|
||||
* <a href="https://github.com/drizzle-team/drizzle-orm">
|
||||
* <img style={{display: "block"}} src="https://authjs.dev/img/adapters/drizzle-orm.png" width="38" />
|
||||
* </a>
|
||||
* </div>
|
||||
*
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install next-auth drizzle-orm @auth/drizzle-adapter
|
||||
* npm install drizzle-kit --save-dev
|
||||
* ```
|
||||
*
|
||||
* @module @auth/drizzle-adapter
|
||||
*/
|
||||
import {
|
||||
accounts,
|
||||
users,
|
||||
sessions,
|
||||
verificationTokens,
|
||||
type DrizzleClient,
|
||||
} from "./schema"
|
||||
import { and, eq } from "drizzle-orm/expressions"
|
||||
import type { Adapter } from "next-auth/adapters"
|
||||
|
||||
/**
|
||||
* ## Setup
|
||||
*
|
||||
* Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object:
|
||||
*
|
||||
* ```js title="pages/api/auth/[...nextauth].js"
|
||||
* import NextAuth from "next-auth"
|
||||
* import GoogleProvider from "next-auth/providers/google"
|
||||
* import { DrizzleAdapter } from "@auth/drizzle-adapter"
|
||||
* import { db } from "./db-schema"
|
||||
*
|
||||
* export default NextAuth({
|
||||
* adapter: DrizzleAdapter(db),
|
||||
* providers: [
|
||||
* GoogleProvider({
|
||||
* clientId: process.env.GOOGLE_CLIENT_ID,
|
||||
* clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
||||
* }),
|
||||
* ],
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* ## Advanced usage
|
||||
*
|
||||
* ### Create the Drizzle schema from scratch
|
||||
*
|
||||
* You'll need to create a database schema that includes the minimal schema for a `next-auth` adapter.
|
||||
* Be sure to use the Drizzle driver version that you're using for your project.
|
||||
*
|
||||
* > This schema is adapted for use in Drizzle and based upon our main [schema](https://authjs.dev/reference/adapters#models)
|
||||
*
|
||||
*
|
||||
* ```json title="db-schema.ts"
|
||||
*
|
||||
* import { integer, pgTable, text, primaryKey } from 'drizzle-orm/pg-core';
|
||||
* import { drizzle } from 'drizzle-orm/node-postgres';
|
||||
* import { migrate } from 'drizzle-orm/node-postgres/migrator';
|
||||
* import { Pool } from 'pg'
|
||||
* import { ProviderType } from 'next-auth/providers';
|
||||
*
|
||||
* export const users = pgTable('users', {
|
||||
* id: text('id').notNull().primaryKey(),
|
||||
* name: text('name'),
|
||||
* email: text("email").notNull(),
|
||||
* emailVerified: integer("emailVerified"),
|
||||
* image: text("image"),
|
||||
* });
|
||||
*
|
||||
* export const accounts = pgTable("accounts", {
|
||||
* userId: text("userId").notNull().references(() => users.id, { onDelete: "cascade" }),
|
||||
* type: text("type").$type<ProviderType>().notNull(),
|
||||
* provider: text("provider").notNull(),
|
||||
* providerAccountId: text("providerAccountId").notNull(),
|
||||
* refresh_token: text("refresh_token"),
|
||||
* access_token: text("access_token"),
|
||||
* expires_at: integer("expires_at"),
|
||||
* token_type: text("token_type"),
|
||||
* scope: text("scope"),
|
||||
* id_token: text("id_token"),
|
||||
* session_state: text("session_state"),
|
||||
* }, (account) => ({
|
||||
* _: primaryKey(account.provider, account.providerAccountId)
|
||||
* }))
|
||||
*
|
||||
* export const sessions = pgTable("sessions", {
|
||||
* userId: text("userId").notNull().references(() => users.id, { onDelete: "cascade" }),
|
||||
* sessionToken: text("sessionToken").notNull().primaryKey(),
|
||||
* expires: integer("expires").notNull(),
|
||||
* })
|
||||
*
|
||||
* export const verificationTokens = pgTable("verificationToken", {
|
||||
* identifier: text("identifier").notNull(),
|
||||
* token: text("token").notNull(),
|
||||
* expires: integer("expires").notNull()
|
||||
* }, (vt) => ({
|
||||
* _: primaryKey(vt.identifier, vt.token)
|
||||
* }))
|
||||
*
|
||||
* const pool = new Pool({
|
||||
* connectionString: "YOUR_CONNECTION_STRING"
|
||||
* });
|
||||
*
|
||||
* export const db = drizzle(pool);
|
||||
*
|
||||
* migrate(db, { migrationsFolder: "./drizzle" })
|
||||
*
|
||||
* ```
|
||||
*
|
||||
**/
|
||||
export function DrizzleAdapter(client: DrizzleClient): Adapter {
|
||||
return {
|
||||
createUser(data) {
|
||||
return client
|
||||
.insert(users)
|
||||
.values({ ...data, id: "123" })
|
||||
.returning()
|
||||
.get()
|
||||
},
|
||||
getUser(data) {
|
||||
return client.select().from(users).where(eq(users.id, data)).get() ?? null
|
||||
},
|
||||
getUserByEmail(data) {
|
||||
return (
|
||||
client.select().from(users).where(eq(users.email, data)).get() ?? null
|
||||
)
|
||||
},
|
||||
createSession(data) {
|
||||
return client.insert(sessions).values(data).returning().get()
|
||||
},
|
||||
getSessionAndUser(data) {
|
||||
return (
|
||||
client
|
||||
.select({
|
||||
session: sessions,
|
||||
user: users,
|
||||
})
|
||||
.from(sessions)
|
||||
.where(eq(sessions.sessionToken, data))
|
||||
.innerJoin(users, eq(users.id, sessions.userId))
|
||||
.get() ?? null
|
||||
)
|
||||
},
|
||||
updateUser(data) {
|
||||
if (!data.id) throw new Error("No user id.")
|
||||
|
||||
return client
|
||||
.update(users)
|
||||
.set(data)
|
||||
.where(eq(users.id, data.id))
|
||||
.returning()
|
||||
.get()
|
||||
},
|
||||
updateSession(data) {
|
||||
return client
|
||||
.update(sessions)
|
||||
.set(data)
|
||||
.where(eq(sessions.sessionToken, data.sessionToken))
|
||||
.returning()
|
||||
.get()
|
||||
},
|
||||
linkAccount(rawAccount) {
|
||||
const updatedAccount = client
|
||||
.insert(accounts)
|
||||
.values(rawAccount)
|
||||
.returning()
|
||||
.get()
|
||||
|
||||
// HACK: Should not need to set `undefined` values here
|
||||
return {
|
||||
...updatedAccount,
|
||||
access_token: updatedAccount.access_token ?? undefined,
|
||||
token_type: updatedAccount.token_type ?? undefined,
|
||||
id_token: updatedAccount.id_token ?? undefined,
|
||||
refresh_token: updatedAccount.refresh_token ?? undefined,
|
||||
scope: updatedAccount.scope ?? undefined,
|
||||
expires_at: updatedAccount.expires_at ?? undefined,
|
||||
session_state: updatedAccount.session_state ?? undefined,
|
||||
}
|
||||
},
|
||||
getUserByAccount(account) {
|
||||
return (
|
||||
client
|
||||
.select()
|
||||
.from(users)
|
||||
.innerJoin(
|
||||
accounts,
|
||||
and(
|
||||
eq(accounts.providerAccountId, account.providerAccountId),
|
||||
eq(accounts.provider, account.provider)
|
||||
)
|
||||
)
|
||||
.get()?.users ?? null
|
||||
)
|
||||
},
|
||||
deleteSession(sessionToken) {
|
||||
return client
|
||||
.delete(sessions)
|
||||
.where(eq(sessions.sessionToken, sessionToken))
|
||||
.returning()
|
||||
.get()
|
||||
},
|
||||
createVerificationToken(token) {
|
||||
return client.insert(verificationTokens).values(token).returning().get()
|
||||
},
|
||||
useVerificationToken(token) {
|
||||
try {
|
||||
return (
|
||||
client
|
||||
.delete(verificationTokens)
|
||||
.where(
|
||||
and(
|
||||
eq(verificationTokens.identifier, token.identifier),
|
||||
eq(verificationTokens.token, token.token)
|
||||
)
|
||||
)
|
||||
.returning()
|
||||
.get() ?? null
|
||||
)
|
||||
} catch (err) {
|
||||
throw new Error("No verification token found.")
|
||||
}
|
||||
},
|
||||
deleteUser(id) {
|
||||
return client.delete(users).where(eq(users.id, id)).returning().get()
|
||||
},
|
||||
unlinkAccount(account) {
|
||||
client
|
||||
.delete(accounts)
|
||||
.where(
|
||||
and(
|
||||
eq(accounts.providerAccountId, account.providerAccountId),
|
||||
eq(accounts.provider, account.provider)
|
||||
)
|
||||
)
|
||||
.run()
|
||||
|
||||
// HACK: void should be fine
|
||||
return undefined
|
||||
},
|
||||
}
|
||||
}
|
||||
63
packages/adapter-drizzle/src/schema.ts
Normal file
63
packages/adapter-drizzle/src/schema.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { integer, sqliteTable, text, primaryKey } from "drizzle-orm/sqlite-core"
|
||||
import { drizzle } from "drizzle-orm/better-sqlite3"
|
||||
import { migrate } from "drizzle-orm/better-sqlite3/migrator"
|
||||
import Database from "better-sqlite3"
|
||||
import { ProviderType } from "next-auth/providers"
|
||||
|
||||
const sqlite = new Database("db.sqlite")
|
||||
|
||||
export const users = sqliteTable("users", {
|
||||
id: text("id").notNull().primaryKey(),
|
||||
name: text("name"),
|
||||
email: text("email").notNull(),
|
||||
emailVerified: integer("emailVerified", { mode: "timestamp_ms" }),
|
||||
image: text("image"),
|
||||
})
|
||||
|
||||
export const accounts = sqliteTable(
|
||||
"accounts",
|
||||
{
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
type: text("type").$type<ProviderType>().notNull(),
|
||||
provider: text("provider").notNull(),
|
||||
providerAccountId: text("providerAccountId").notNull(),
|
||||
refresh_token: text("refresh_token"),
|
||||
access_token: text("access_token"),
|
||||
expires_at: integer("expires_at"),
|
||||
token_type: text("token_type"),
|
||||
scope: text("scope"),
|
||||
id_token: text("id_token"),
|
||||
session_state: text("session_state"),
|
||||
},
|
||||
(account) => ({
|
||||
nameDoesntMatter: primaryKey(account.provider, account.providerAccountId),
|
||||
})
|
||||
)
|
||||
|
||||
export const sessions = sqliteTable("sessions", {
|
||||
sessionToken: text("sessionToken").notNull().primaryKey(),
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
|
||||
})
|
||||
|
||||
export const verificationTokens = sqliteTable(
|
||||
"verificationToken",
|
||||
{
|
||||
identifier: text("identifier").notNull(),
|
||||
token: text("token").notNull(),
|
||||
expires: integer("expires", { mode: "timestamp_ms" }).notNull(),
|
||||
},
|
||||
(vt) => ({
|
||||
nameDoesntMatter: primaryKey(vt.identifier, vt.token),
|
||||
})
|
||||
)
|
||||
|
||||
export const db = drizzle(sqlite)
|
||||
|
||||
export type DrizzleClient = typeof db
|
||||
|
||||
migrate(db, { migrationsFolder: "./drizzle" })
|
||||
68
packages/adapter-drizzle/tests/index.test.ts
Normal file
68
packages/adapter-drizzle/tests/index.test.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { randomUUID, runBasicTests } from "@next-auth/adapter-test"
|
||||
import { DrizzleAdapter } from "../src"
|
||||
import { db, users, accounts, sessions, verificationTokens } from '../src/schema'
|
||||
import { eq, and } from 'drizzle-orm/expressions';
|
||||
|
||||
|
||||
runBasicTests({
|
||||
adapter: DrizzleAdapter(db),
|
||||
db: {
|
||||
id() {
|
||||
return randomUUID()
|
||||
},
|
||||
connect: async () => {
|
||||
await Promise.all([
|
||||
db.delete(sessions).run(),
|
||||
db.delete(accounts).run(),
|
||||
db.delete(verificationTokens).run(),
|
||||
db.delete(users).run(),
|
||||
])
|
||||
},
|
||||
disconnect: async () => {
|
||||
await Promise.all([
|
||||
db.delete(sessions).run(),
|
||||
db.delete(accounts).run(),
|
||||
db.delete(verificationTokens).run(),
|
||||
db.delete(users).run(),
|
||||
])
|
||||
},
|
||||
user: (id) => db
|
||||
.select()
|
||||
.from(users)
|
||||
.where(eq(users.id, id))
|
||||
.get() ?? null,
|
||||
session: (sessionToken) => db
|
||||
.select()
|
||||
.from(sessions)
|
||||
.where(eq(sessions.sessionToken, sessionToken))
|
||||
.get() ?? null,
|
||||
account: (provider_providerAccountId) => {
|
||||
return db
|
||||
.select()
|
||||
.from(accounts)
|
||||
.where(
|
||||
eq(
|
||||
accounts.providerAccountId,
|
||||
provider_providerAccountId.providerAccountId
|
||||
)
|
||||
)
|
||||
.get()
|
||||
?? null
|
||||
},
|
||||
verificationToken: (identifier_token) => db
|
||||
.select()
|
||||
.from(verificationTokens)
|
||||
.where(
|
||||
and(
|
||||
eq(
|
||||
verificationTokens.token,
|
||||
identifier_token.token
|
||||
),
|
||||
eq(
|
||||
verificationTokens.identifier,
|
||||
identifier_token.identifier
|
||||
)
|
||||
)
|
||||
).get() ?? null,
|
||||
},
|
||||
})
|
||||
21
packages/adapter-drizzle/tsconfig.json
Normal file
21
packages/adapter-drizzle/tsconfig.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": ".",
|
||||
"rootDir": "src",
|
||||
"skipDefaultLibCheck": true,
|
||||
"skipLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"stripInternal": true,
|
||||
"target": "ES2020",
|
||||
},
|
||||
"exclude": [
|
||||
"tests",
|
||||
"*.js",
|
||||
"*.d.ts*",
|
||||
]
|
||||
}
|
||||
@@ -9,10 +9,10 @@
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install next-auth @next-auth/dyanamodb-adapter
|
||||
* npm install next-auth @next-auth/dynamodb-adapter
|
||||
* ```
|
||||
*
|
||||
* @module @next-auth/dyanamodb-adapter
|
||||
* @module @next-auth/dynamodb-adapter
|
||||
*/
|
||||
import { v4 as uuid } from "uuid"
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install install next-auth @next-auth/sequelize-adapter sequelize
|
||||
* npm install next-auth @next-auth/sequelize-adapter sequelize
|
||||
* ```
|
||||
*
|
||||
* @module @next-auth/sequelize-adapter
|
||||
|
||||
@@ -44,7 +44,7 @@ export interface AzureADB2CProfile {
|
||||
* 2. [App Registration](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications)
|
||||
* 3. [User Flow](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows)
|
||||
*
|
||||
* For the step "User attributes and token claims" you might want to set the following:
|
||||
* For the step "User attributes and token claims" set the following:
|
||||
*
|
||||
* - Collect attribute:
|
||||
* - Email Address
|
||||
|
||||
@@ -39,7 +39,7 @@ export interface EmailConfig extends CommonProviderOptions {
|
||||
* @default 86400
|
||||
*/
|
||||
maxAge?: number
|
||||
/** [Documentation](https://authjs.dev/reference/providers/email#customizing-emails) */
|
||||
/** [Documentation](https://authjs.dev/guides/providers/email#customizing-emails) */
|
||||
sendVerificationRequest: (
|
||||
params: SendVerificationRequestParams
|
||||
) => Awaitable<void>
|
||||
@@ -55,7 +55,7 @@ export interface EmailConfig extends CommonProviderOptions {
|
||||
* }
|
||||
* })
|
||||
* ```
|
||||
* [Documentation](https://authjs.dev/reference/providers/email#customizing-the-verification-token)
|
||||
* [Documentation](https://authjs.dev/guides/providers/email#customizing-the-verification-token)
|
||||
*/
|
||||
generateVerificationToken?: () => Awaitable<string>
|
||||
/** If defined, it is used to hash the verification token when saving to the database . */
|
||||
@@ -72,7 +72,7 @@ export interface EmailConfig extends CommonProviderOptions {
|
||||
* By default, we treat email addresses as all lower case,
|
||||
* but you can override this function to change this behavior.
|
||||
*
|
||||
* [Documentation](https://authjs.dev/reference/providers/email#normalizing-the-e-mail-address) | [RFC 2821](https://tools.ietf.org/html/rfc2821) | [Email syntax](https://en.wikipedia.org/wiki/Email_address#Syntax)
|
||||
* [Documentation](https://authjs.dev/guides/providers/email#normalizing-the-e-mail-address) | [RFC 2821](https://tools.ietf.org/html/rfc2821) | [Email syntax](https://en.wikipedia.org/wiki/Email_address#Syntax)
|
||||
*/
|
||||
normalizeIdentifier?: (identifier: string) => string
|
||||
}
|
||||
|
||||
@@ -150,6 +150,10 @@ export interface OAuth2Config<Profile>
|
||||
checks?: Array<"pkce" | "state" | "none" | "nonce">
|
||||
clientId?: string
|
||||
clientSecret?: string
|
||||
/**
|
||||
* Pass overrides to the underlying OAuth library.
|
||||
* See [`oauth4webapi` client](https://github.com/panva/oauth4webapi/blob/main/docs/interfaces/Client.md) for details.
|
||||
*/
|
||||
client?: Partial<Client>
|
||||
style?: OAuthProviderButtonStyles
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,11 @@ export default function Reddit(options) {
|
||||
authorization: "https://www.reddit.com/api/v1/authorize?scope=identity",
|
||||
token: "https://www.reddit.com/api/v1/access_token",
|
||||
userinfo: "https://oauth.reddit.com/api/v1/me",
|
||||
style: {
|
||||
logo: "/reddit.svg",
|
||||
bg: "#fff",
|
||||
text: "#000",
|
||||
},
|
||||
options,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
/** @type {import(".").OAuthProvider} */
|
||||
export default function Yandex(options) {
|
||||
return {
|
||||
id: "yandex",
|
||||
name: "Yandex",
|
||||
type: "oauth",
|
||||
authorization:
|
||||
"https://oauth.yandex.ru/authorize?scope=login:email+login:info",
|
||||
token: "https://oauth.yandex.ru/token",
|
||||
userinfo: "https://login.yandex.ru/info?format=json",
|
||||
profile(profile) {
|
||||
return {
|
||||
id: profile.id,
|
||||
name: profile.real_name,
|
||||
email: profile.default_email,
|
||||
image: profile.is_avatar_empty
|
||||
? null
|
||||
: `https://avatars.yandex.net/get-yapic/${profile.default_avatar_id}/islands-200`,
|
||||
}
|
||||
},
|
||||
options,
|
||||
}
|
||||
}
|
||||
155
packages/core/src/providers/yandex.ts
Normal file
155
packages/core/src/providers/yandex.ts
Normal file
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* <div style={{backgroundColor: "#ffcc00", display: "flex", justifyContent: "space-between", color: "#000", padding: 16}}>
|
||||
* <span>Built-in <b>Yandex</b> integration.</span>
|
||||
* <a href="https://github.com">
|
||||
* <img style={{display: "block"}} src="https://authjs.dev/img/providers/yandex.svg" height="48" width="48"/>
|
||||
* </a>
|
||||
* </div>
|
||||
*
|
||||
* ---
|
||||
* @module providers/yandex
|
||||
*/
|
||||
|
||||
import { OAuthConfig, OAuthUserConfig } from "."
|
||||
|
||||
/**
|
||||
* @see [Getting information about the user](https://yandex.com/dev/id/doc/en/user-information)
|
||||
* @see [Access to email address](https://yandex.com/dev/id/doc/en/user-information#email-access)
|
||||
* @see [Access to the user's profile picture](https://yandex.com/dev/id/doc/en/user-information#avatar-access)
|
||||
* @see [Access to the date of birth](https://yandex.com/dev/id/doc/en/user-information#birthday-access)
|
||||
* @see [Access to login, first name, last name, and gender](https://yandex.com/dev/id/doc/en/user-information#name-access)
|
||||
* @see [Access to the phone number](https://yandex.com/dev/id/doc/en/user-information#phone-access)
|
||||
*/
|
||||
export interface YandexProfile {
|
||||
/** User's Yandex login. */
|
||||
login: string
|
||||
/** Yandex user's unique ID. */
|
||||
id: string
|
||||
/**
|
||||
* The ID of the app the OAuth token in the request was issued for.
|
||||
* Available in the [app properties](https://oauth.yandex.com/). To open properties, click the app name.
|
||||
*/
|
||||
client_id: string
|
||||
/** Authorized Yandex user ID. It is formed on the Yandex side based on the `client_id` and `user_id` pair. */
|
||||
psuid: string
|
||||
/** An array of the user's email addresses. Currently only includes the default email address. */
|
||||
emails?: string[]
|
||||
/** The default email address for contacting the user. */
|
||||
default_email?: string
|
||||
/**
|
||||
* Indicates that the stub (profile picture that is automatically assigned when registering in Yandex)
|
||||
* ID is specified in the `default_avatar_id` field.
|
||||
*/
|
||||
is_avatar_empty?: boolean
|
||||
/**
|
||||
* ID of the Yandex user's profile picture.
|
||||
* The profile picture with this ID can be downloaded via a link that looks like this:
|
||||
* @example "https://avatars.yandex.net/get-yapic/31804/BYkogAC6AoB17bN1HKRFAyKiM4-1/islands-200"
|
||||
*/
|
||||
default_avatar_id?:
|
||||
| "islands-small"
|
||||
| "islands-34"
|
||||
| "islands-middle"
|
||||
| "islands-50"
|
||||
| "islands-retina-small"
|
||||
| "islands-68"
|
||||
| "islands-75"
|
||||
| "islands-retina-middle"
|
||||
| "islands-retina-50"
|
||||
| "islands-200"
|
||||
/**
|
||||
* The user's date of birth in YYYY-MM-DD format.
|
||||
* Unknown elements of the date are filled in with zeros, such as: `0000-12-23`.
|
||||
* If the user's date of birth is unknow, birthday will be `null`
|
||||
*/
|
||||
birthday?: string | null
|
||||
first_name?: string
|
||||
last_name?: string
|
||||
display_name?: string
|
||||
/**
|
||||
* The first and last name that the user specified in Yandex ID.
|
||||
* Non-Latin characters of the first and last names are presented in Unicode format.
|
||||
*/
|
||||
real_name?: string
|
||||
/** User's gender. Possible values: Male: `male', Female: `female`, Unknown gender: `null` */
|
||||
sex?: string
|
||||
/**
|
||||
* The default phone number for contacting the user.
|
||||
* The API can exclude the user's phone number from the response at its discretion.
|
||||
* The field contains the following parameters:
|
||||
* id: Phone number ID.
|
||||
* number: The user's phone number.
|
||||
*/
|
||||
default_phone?: { id: number; number: string }
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Yandex login to your page
|
||||
*
|
||||
* ## Example
|
||||
*
|
||||
* ```ts
|
||||
* import { Auth } from "@auth/core"
|
||||
* import Yandex from "@auth/core/providers/yandex"
|
||||
*
|
||||
* const request = new Request("https://example.com")
|
||||
* const response = await Auth(request, {
|
||||
* providers: [Yandex({ clientId: "", clientSecret: "" })],
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
* ## Resources
|
||||
*
|
||||
* @see [Yandex - Creating an OAuth app](https://yandex.com/dev/id/doc/en/register-client#create)
|
||||
* @see [Yandex - Manage OAuth apps](https://oauth.yandex.com/)
|
||||
* @see [Yandex - OAuth documentation](https://yandex.com/dev/id/doc/en/)
|
||||
* @see [Learn more about OAuth](https://authjs.dev/concepts/oauth)
|
||||
* @see [Source code](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/yandex.ts)
|
||||
*
|
||||
*:::tip
|
||||
* The Yandex provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/yandex.ts).
|
||||
* To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/providers/custom-provider#override-default-options).
|
||||
* :::
|
||||
*
|
||||
* :::info **Disclaimer**
|
||||
* If you think you found a bug in the default configuration, you can [open an issue](https://authjs.dev/new/provider-issue).
|
||||
*
|
||||
* Auth.js strictly adheres to the specification and it cannot take responsibility for any deviation from
|
||||
* the spec by the provider. You can open an issue, but if the problem is non-compliance with the spec,
|
||||
* we might not pursue a resolution. You can ask for more help in [Discussions](https://authjs.dev/new/github-discussions).
|
||||
* :::
|
||||
*/
|
||||
export default function Yandex(
|
||||
options: OAuthUserConfig<YandexProfile>
|
||||
): OAuthConfig<YandexProfile> {
|
||||
return {
|
||||
id: "yandex",
|
||||
name: "Yandex",
|
||||
type: "oauth",
|
||||
/** @see [Data access](https://yandex.com/dev/id/doc/en/register-client#access) */
|
||||
authorization:
|
||||
"https://oauth.yandex.ru/authorize?scope=login:info+login:email+login:avatar",
|
||||
token: "https://oauth.yandex.ru/token",
|
||||
userinfo: "https://login.yandex.ru/info?format=json",
|
||||
profile(profile) {
|
||||
return {
|
||||
id: profile.id,
|
||||
name: profile.display_name ?? profile.real_name ?? profile.first_name,
|
||||
email: profile.default_email ?? profile.emails?.[0] ?? null,
|
||||
image:
|
||||
!profile.is_avatar_empty && profile.default_avatar_id
|
||||
? `https://avatars.yandex.net/get-yapic/${profile.default_avatar_id}/islands-200`
|
||||
: null,
|
||||
}
|
||||
},
|
||||
style: {
|
||||
logo: "/yandex.svg",
|
||||
logoDark: "/yandex.svg",
|
||||
bg: "#ffcc00",
|
||||
text: "#000",
|
||||
bgDark: "#ffcc00",
|
||||
textDark: "#000",
|
||||
},
|
||||
options,
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ export default function Reddit(options) {
|
||||
name: "Reddit",
|
||||
type: "oauth",
|
||||
authorization: "https://www.reddit.com/api/v1/authorize?scope=identity",
|
||||
token: " https://www.reddit.com/api/v1/access_token",
|
||||
token: "https://www.reddit.com/api/v1/access_token",
|
||||
userinfo: "https://oauth.reddit.com/api/v1/me",
|
||||
profile(profile) {
|
||||
return {
|
||||
@@ -15,6 +15,11 @@ export default function Reddit(options) {
|
||||
image: null,
|
||||
}
|
||||
},
|
||||
style: {
|
||||
logo: "https://raw.githubusercontent.com/nextauthjs/next-auth/main/packages/next-auth/provider-logos/reddit.svg",
|
||||
bg: "#fff",
|
||||
text: "#000",
|
||||
},
|
||||
options,
|
||||
}
|
||||
}
|
||||
|
||||
1299
pnpm-lock.yaml
generated
1299
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
22
turbo.json
22
turbo.json
@@ -51,7 +51,26 @@
|
||||
"env": ["UPSTASH_REDIS_KEY", "UPSTASH_REDIS_URL"]
|
||||
},
|
||||
"docs#dev": {
|
||||
"dependsOn": ["^build"],
|
||||
"dependsOn": [
|
||||
"@auth/core#build",
|
||||
"@auth/sveltekit#build",
|
||||
"@next-auth/dgraph-adapter#build",
|
||||
"@next-auth/dynamodb-adapter#build",
|
||||
"@next-auth/fauna-adapter#build",
|
||||
"@next-auth/firebase-adapter#build",
|
||||
"@next-auth/mikro-orm-adapter#build",
|
||||
"@next-auth/mongodb-adapter#build",
|
||||
"@next-auth/neo4j-adapter#build",
|
||||
"@next-auth/pouchdb-adapter#build",
|
||||
"@next-auth/prisma-adapter#build",
|
||||
"@next-auth/sequelize-adapter#build",
|
||||
"@next-auth/supabase-adapter#build",
|
||||
"@next-auth/typeorm-legacy-adapter#build",
|
||||
"@next-auth/upstash-redis-adapter#build",
|
||||
"@next-auth/xata-adapter#build",
|
||||
"^build",
|
||||
"next-auth#build"
|
||||
],
|
||||
"cache": false
|
||||
},
|
||||
"docs#build": {
|
||||
@@ -72,6 +91,7 @@
|
||||
"@next-auth/typeorm-legacy-adapter#build",
|
||||
"@next-auth/upstash-redis-adapter#build",
|
||||
"@next-auth/xata-adapter#build",
|
||||
"^build",
|
||||
"next-auth#build"
|
||||
],
|
||||
"outputs": [
|
||||
|
||||
Reference in New Issue
Block a user