Compare commits

...

34 Commits

Author SHA1 Message Date
Thang Vu
98782a6a9b Update release.yml 2023-07-26 23:30:16 +07:00
Thang Vu
e9fefaad11 pin different turbo version 2023-07-26 23:08:13 +07:00
Steven Yung
c0f9af4c56 docs: fix GitHub star counter position (#8143) 2023-07-26 15:04:12 +02:00
Balázs Orbán
c7b36f45a3 docs: update nodemailer link
Fixes #8141
2023-07-26 14:57:22 +02:00
Thang Vu
68ff69f9eb chore: upload turbo cache (#8128)
* Update index.ts

* Revert "Update index.ts"

This reverts commit f494291c7385d50e5e8cba65258893925808fa43.

* try this

* Update release.yml

* Update release.yml

* try

* Update turbo.json

* Update release.yml

* Update README.md

* Revert "Update README.md"

This reverts commit a5e56687e0bb60fcefb6c7a2f36d7135fb365e61.

* Update pnpm-workspace.yaml
2023-07-25 22:31:20 +07:00
Thang Vu
23c0a393da chore: add summarize flag for test 2023-07-24 23:31:31 +07:00
Thang Vu
f130f62a91 chore: ignore apps in test 2023-07-24 20:19:45 +07:00
Thang Vu
c111b436d2 chore: update turbo configurations 2023-07-24 19:39:06 +07:00
Thang Vu
ea895b8864 chore: add TURBO env vars back 2023-07-24 19:20:31 +07:00
Thang Vu
cfedc3b1a3 chore: bump next in dev 2023-07-24 19:01:12 +07:00
Thang Vu
287a5fc05a chore: clean up dev & lock file 2023-07-24 19:00:26 +07:00
Thang Vu
f3ad659e91 chore: remove TURBO env vars 2023-07-24 18:52:25 +07:00
Thang Vu
48b9a0203e chore: dev environment clean up 2023-07-23 14:13:31 +07:00
Thang Vu
39fbccb783 fix: follow up allow EndpointRequest to return void type 2023-07-23 14:10:46 +07:00
Junseo
f207e94146 fix(ts): allow EndpointRequest to return void type (#8112)
* fix: fix: enable EndpointRequest type to return void type

* Update packages/next-auth/src/providers/oauth.ts

* Update packages/core/src/providers/oauth.ts

---------

Co-authored-by: Thang Vu <hi@thvu.dev>
2023-07-22 23:05:29 +07:00
Serdar ŞEN
b845729cdb docs: update getting started commands for docs (#8040)
Co-authored-by: Thang Vu <hi@thvu.dev>
2023-07-22 12:53:03 +07:00
GitHub Actions
e459d2d7e2 chore(release): bump package version(s) [skip ci] 2023-07-18 14:40:11 +00:00
Thang Vu
db1fd9007c fix(ts): types in sveltekit 2023-07-18 21:29:04 +07:00
Thang Vu
0439fc5fc6 feat(providers): add request param to sendVerificationRequest (#8071)
Co-authored-by: Corey Jepperson <11298888+acoreyj@users.noreply.github.com>
2023-07-18 15:39:11 +02:00
Benjamin Tamasi
d0dd2ababc fix(sveltekit): prefix for getSession url (#6478)
* [SvelteKit] fix getSession url

remove `/api` prefix from getSession function.

* Update packages/frameworks-sveltekit/src/lib/index.ts

---------

Co-authored-by: Thang Vu <hi@thvu.dev>
2023-07-16 21:01:25 +07:00
Thang Vu
ba58d48dba fix(providers): add authorization params for AzureAD (#8047)
https: //github.com/nextauthjs/next-auth/pull/5668

Co-authored-by: Andres Jose Sebastian Rincon Gonzalez <2531975+stianrincon@users.noreply.github.com>
2023-07-15 22:01:24 +07:00
Thang Vu
a8d76ed440 fix(ts): require id for updateUser param (#8044)
https: //github.com/nextauthjs/next-auth/pull/5431

Co-authored-by: Yuri Sulyma <453486+ysulyma@users.noreply.github.com>
2023-07-15 17:18:15 +07:00
Thang Vu
3d7b8720db chore(docs): OIDC example for BoxyHQ (#8032)
chore(docs): OIDC example for BoxyHQ

Co-authored-by: Deepak Prabhakara <deepak@boxyhq.com>
2023-07-13 23:43:10 +07:00
Francis Gulotta
1e886b97bc fix(EmailProvider): proper required fields and allow all nodemailer types (#8016) 2023-07-11 18:01:47 +02:00
Tal Aharoni
ecb14ccecd fix: correct Descope provider config (#8003) 2023-07-11 12:51:32 +02:00
GitHub Actions
8cee24d4ab chore(release): bump package version(s) [skip ci] 2023-07-10 19:40:53 +00:00
Balázs Orbán
0189a197be chore: fix syntax in package.json 2023-07-10 21:29:38 +02:00
Balázs Orbán
c44bf75c65 fix: add svelte as peer dependency
Fixes #8004
2023-07-10 21:27:16 +02:00
GitHub Actions
cf13b6c7e3 chore(release): bump package version(s) [skip ci] 2023-07-10 16:21:19 +00:00
Dahoom152
dc1a79e547 fix: drop svelte as peer dependency (#7989)
* optionally bumped to svelte 4.0

* removed redundancy

* Update package.json

* Update package.json

---------

Co-authored-by: Balázs Orbán <info@balazsorban.com>
2023-07-10 18:10:29 +02:00
arjun
78964c115b fix(adapters): add missing .js file extension (#7971)
Add missing .js file extension
2023-07-07 17:05:07 +02:00
Balázs Orbán
7fa51e2a61 docs: clarify preview deployment guide 2023-07-06 16:44:31 +02:00
Gwenaël Gallon
a79774f6e8 fix(docs): fix catch-all route path (#7925) 2023-07-01 01:36:23 +02:00
Fatih Solhan
f779f05906 docs: remove extra 'if' in comment (#7914) 2023-06-30 21:00:28 +02:00
34 changed files with 1235 additions and 6773 deletions

View File

@@ -8,6 +8,10 @@ on:
- next
- 3.x
pull_request:
paths-ignore:
- ".vscode/**"
- "**/*.md"
- ".github/ISSUE_TEMPLATE/**"
# TODO: Support latest releases
workflow_dispatch:
inputs:
@@ -56,6 +60,8 @@ on:
- "adapter-upstash-redis"
- "adapter-xata"
- "next-auth"
env:
FORCE_COLOR: true
jobs:
test:
@@ -75,6 +81,11 @@ jobs:
cache: "pnpm"
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm build
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
- name: Run tests
run: pnpm test
timeout-minutes: 15
@@ -83,6 +94,11 @@ jobs:
UPSTASH_REDIS_KEY: ${{ secrets.UPSTASH_REDIS_KEY }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
- name: Upload Turbo artifacts
uses: actions/upload-artifact@v3
with:
name: turbo-report
path: .turbo/runs/
# - name: Run E2E tests
# if: github.repository == 'nextauthjs/next-auth'
# run: pnpm e2e

View File

@@ -22,7 +22,7 @@
"@prisma/client": "^3",
"@supabase/supabase-js": "^2.0.5",
"faunadb": "^4",
"next": "13.3.0",
"next": "13.4.0",
"next-auth": "workspace:*",
"nodemailer": "^6",
"react": "^18",

View File

@@ -2,11 +2,11 @@ import { Auth, type AuthConfig } from "@auth/core"
// Providers
import Apple from "@auth/core/providers/apple"
import Asgardeo from "@auth/core/providers/asgardeo"
// import Asgardeo from "@auth/core/providers/asgardeo"
import Auth0 from "@auth/core/providers/auth0"
import AzureAD from "@auth/core/providers/azure-ad"
import AzureB2C from "@auth/core/providers/azure-ad-b2c"
import BeyondIdentity from "@auth/core/providers/beyondidentity"
// import BeyondIdentity from "@auth/core/providers/beyondidentity"
import BoxyHQSAML from "@auth/core/providers/boxyhq-saml"
// import Cognito from "@auth/core/providers/cognito"
import Credentials from "@auth/core/providers/credentials"
@@ -86,8 +86,8 @@ export const authConfig: AuthConfig = {
return { name: "Fill Murray", email: "bill@fillmurray.com", image: "https://www.fillmurray.com/64/64", id: "1", foo: "" }
},
}),
Apple({ clientId: process.env.APPLE_ID, clientSecret: process.env.APPLE_SECRET }),
Asgardeo({ clientId: process.env.ASGARDEO_CLIENT_ID, clientSecret: process.env.ASGARDEO_CLIENT_SECRET, issuer: process.env.ASGARDEO_ISSUER }),
Apple({ clientId: process.env.APPLE_ID, clientSecret: process.env.APPLE_SECRET as string }),
// Asgardeo({ clientId: process.env.ASGARDEO_CLIENT_ID, clientSecret: process.env.ASGARDEO_CLIENT_SECRET, issuer: process.env.ASGARDEO_ISSUER }),
Auth0({ clientId: process.env.AUTH0_ID, clientSecret: process.env.AUTH0_SECRET, issuer: process.env.AUTH0_ISSUER }),
AzureAD({
clientId: process.env.AZURE_AD_CLIENT_ID,
@@ -95,11 +95,11 @@ export const authConfig: AuthConfig = {
tenantId: process.env.AZURE_AD_TENANT_ID,
}),
AzureB2C({ clientId: process.env.AZURE_B2C_ID, clientSecret: process.env.AZURE_B2C_SECRET, issuer: process.env.AZURE_B2C_ISSUER }),
BeyondIdentity({
clientId: process.env.BEYOND_IDENTITY_CLIENT_ID,
clientSecret: process.env.BEYOND_IDENTITY_CLIENT_SECRET,
issuer: process.env.BEYOND_IDENTITY_ISSUER,
}),
// BeyondIdentity({
// clientId: process.env.BEYOND_IDENTITY_CLIENT_ID,
// clientSecret: process.env.BEYOND_IDENTITY_CLIENT_SECRET,
// issuer: process.env.BEYOND_IDENTITY_ISSUER,
// }),
BoxyHQSAML({ issuer: "https://jackson-demo.boxyhq.com", clientId: "tenant=boxyhq.com&product=saml-demo.boxyhq.com", clientSecret: "dummy" }),
// Cognito({ clientId: process.env.COGNITO_ID, clientSecret: process.env.COGNITO_SECRET, issuer: process.env.COGNITO_ISSUER }),
Descope({ clientId: process.env.DESCOPE_ID, clientSecret: process.env.DESCOPE_SECRET }),
@@ -108,7 +108,7 @@ export const authConfig: AuthConfig = {
Facebook({ clientId: process.env.FACEBOOK_ID, clientSecret: process.env.FACEBOOK_SECRET }),
Foursquare({ clientId: process.env.FOURSQUARE_ID, clientSecret: process.env.FOURSQUARE_SECRET }),
Freshbooks({ clientId: process.env.FRESHBOOKS_ID, clientSecret: process.env.FRESHBOOKS_SECRET }),
GitHub({ clientId: process.env.GITHUB_ID, clientSecret: process.env.GITHUB_SECRET, redirectProxy: process.env.AUTH_REDIRECT_PROXY_URL }),
GitHub({ clientId: process.env.GITHUB_ID, clientSecret: process.env.GITHUB_SECRET, redirectProxyUrl: process.env.AUTH_REDIRECT_PROXY_URL }),
Gitlab({ clientId: process.env.GITLAB_ID, clientSecret: process.env.GITLAB_SECRET }),
Google({ clientId: process.env.GOOGLE_ID, clientSecret: process.env.GOOGLE_SECRET }),
// IDS4({ clientId: process.env.IDS4_ID, clientSecret: process.env.IDS4_SECRET, issuer: process.env.IDS4_ISSUER }),
@@ -117,7 +117,7 @@ export const authConfig: AuthConfig = {
Line({ clientId: process.env.LINE_ID, clientSecret: process.env.LINE_SECRET }),
LinkedIn({ clientId: process.env.LINKEDIN_ID, clientSecret: process.env.LINKEDIN_SECRET }),
Mailchimp({ clientId: process.env.MAILCHIMP_ID, clientSecret: process.env.MAILCHIMP_SECRET }),
Notion({ clientId: process.env.NOTION_ID, clientSecret: process.env.NOTION_SECRET, redirectUri: process.env.NOTION_REDIRECT_URI }),
Notion({ clientId: process.env.NOTION_ID, clientSecret: process.env.NOTION_SECRET, redirectUri: process.env.NOTION_REDIRECT_URI as string }),
// Okta({ clientId: process.env.OKTA_ID, clientSecret: process.env.OKTA_SECRET, issuer: process.env.OKTA_ISSUER }),
Osu({ clientId: process.env.OSU_CLIENT_ID, clientSecret: process.env.OSU_CLIENT_SECRET }),
Patreon({ clientId: process.env.PATREON_ID, clientSecret: process.env.PATREON_SECRET }),
@@ -162,4 +162,4 @@ function AuthHandler(...args: any[]) {
export default AuthHandler(authConfig)
export const config = { runtime: "experimental-edge" }
export const config = { runtime: "edge" }

View File

@@ -37,22 +37,31 @@ This documentation site is based on the [Docusaurus](https://docusaurus.io) fram
To start a local environment of this project, please do the following.
1. Clone the repository.
1. Clone the repo:
```bash
$ git clone https://github.com/nextauthjs/docs.git
```sh
git clone git@github.com:nextauthjs/next-auth.git
cd next-auth
```
2. Install dependencies
2. Set up the correct pnpm version, using [Corepack](https://nodejs.org/api/corepack.html). Run the following in the project'a root:
```bash
$ npm install
```sh
corepack enable pnpm
```
3. Start the development server
(Now, if you run `pnpm --version`, it should print the same verion as the `packageManager` property in the [`package.json` file](https://github.com/nextauthjs/next-auth/blob/main/package.json))
3. Install packages. Developing requires Node.js v18:
```sh
pnpm install
```
4. Start the development server
```bash
$ npm start
$ pnpm dev:docs
```
And thats all! Now you should have a local copy of this docs site running at [localhost:3000](http://localhost:3000)!

View File

@@ -34,7 +34,7 @@ npm install -D nodemailer
## 2. Setting up a SMTP service
Next we need a [SMTP service](https://sendgrid.com/blog/what-is-an-smtp-server/) which will be in charge of sending emails from our application. There's a number of services available for this, however [here are the ones](http://nodemailer.com/smtp/well-known/) known to work with `nodemailer`.
Next we need a [SMTP service](https://sendgrid.com/blog/what-is-an-smtp-server/) which will be in charge of sending emails from our application. There's a number of services available for this, however [here are the ones](https://community.nodemailer.com/2-0-0-beta/setup-smtp/well-known-services) known to work with `nodemailer`.
:::info
For this tutorial, we're going to be using [Sendgrid](https://sendgrid.com/), but any of the services linked above should work the same

View File

@@ -34,7 +34,7 @@ Most OAuth providers cannot be configured with multiple callback URLs or using a
However, Auth.js **supports Preview deployments**, even **with OAuth providers**:
1. Determine a stable deployment URL. Eg.: A deployment whose URL does not change between builds, for example. `auth.yourdomain.com`),
1. Determine a stable deployment URL. Eg.: A deployment whose URL does not change between builds, for example. `auth.yourdomain.com` (using a subdomain is not a requirement, this can simply be the main site's URL too.),
2. Set `AUTH_REDIRECT_PROXY_URL` to that URL, adding the path up until your `[...nextauth]` route. Eg.: (`https://auth.yourdomain.com/api/auth`)
3. For your OAuth provider, set the callback URL using the stable deployment URL. Eg.: For GitHub `https://auth.yourdomain.com/api/auth/callback/github`)
@@ -42,6 +42,9 @@ However, Auth.js **supports Preview deployments**, even **with OAuth providers**
To support preview deployments, the `AUTH_SECRET` value needs to be the same for the stable deployment and deployments that will need OAuth support.
:::
:::note
If you are storing users in a [database](reference/adapters), we recommend using a different OAuth app for development/production so that you don't mix your test and production user base.
:::
<details>
<summary>

View File

@@ -112,6 +112,7 @@ providers: [
identifier: email,
url,
provider: { server, from },
request // for example can be used to get the user agent (`request.headers.get("user-agent")`) to parse and pass on to the user in the email so they can be more confident they originated the request
}) {
/* your function */
},

View File

@@ -91,7 +91,7 @@ html[data-theme="dark"] .navbar__item.navbar__link[href*="npm"]:before {
position: absolute;
color: #000;
top: -10px;
right: -45px;
right: 4px;
font-size: 9px;
background-color: #ccc;
padding: 2px 5px;

View File

@@ -101,13 +101,13 @@ export default function Home() {
.fetch("https://api.github.com/repos/nextauthjs/next-auth")
.then((res) => res.json())
.then((data) => {
const navLinks = document.getElementsByClassName(
"navbar__item navbar__link"
const githubLink = document.querySelector(
".navbar__item.navbar__link[href*='github']"
)
const githubStat = document.createElement("span")
githubStat.innerHTML = kFormatter(data.stargazers_count)
githubStat.className = "github-counter"
navLinks[4].appendChild(githubStat)
githubLink.appendChild(githubStat)
})
}, [])
return (

View File

@@ -6,8 +6,8 @@
"scripts": {
"build:app": "turbo run build --filter=next-auth-app",
"build:docs": "turbo run build --filter=docs",
"build": "turbo run build --filter=next-auth --filter=@next-auth/* --filter=@auth/* --no-deps",
"test": "turbo run test --concurrency=1 --filter=[HEAD^1] --filter=./packages/* --filter=!@*upstash* --filter=!*dynamodb-*",
"build": "turbo run build --filter=next-auth --filter=@next-auth/* --filter=@auth/* --no-deps --summarize",
"test": "turbo run test --concurrency=1 --summarize --filter=[HEAD^1] --filter=./packages/* --filter=!@*upstash* --filter=!*dynamodb-* --filter=!*app*",
"clean": "turbo run clean --no-cache",
"dev:db": "turbo run dev --parallel --continue --filter=next-auth-app...",
"dev": "turbo run dev --parallel --continue --filter=next-auth-app... --filter=!./packages/adapter-*",
@@ -43,7 +43,7 @@
"eslint-plugin-svelte3": "^4.0.0",
"prettier": "2.8.1",
"prettier-plugin-svelte": "^2.8.1",
"turbo": "1.10.1",
"turbo": "1.10.3",
"typescript": "4.9.4"
},
"engines": {

View File

@@ -1,7 +1,7 @@
{
"name": "@auth/dynamodb-adapter",
"repository": "https://github.com/nextauthjs/next-auth",
"version": "1.0.0",
"version": "1.0.1",
"description": "AWS DynamoDB adapter for next-auth.",
"keywords": [
"next-auth",

View File

@@ -265,9 +265,8 @@ export function DynamoDBAdapter(
const data = await client.update({
TableName,
Key: {
// next-auth type is incorrect it should be Partial<AdapterUser> & {id: string} instead of just Partial<AdapterUser>
[pk]: `USER#${user.id as string}`,
[sk]: `USER#${user.id as string}`,
[pk]: `USER#${user.id}`,
[sk]: `USER#${user.id}`,
},
UpdateExpression,
ExpressionAttributeNames,

View File

@@ -1,6 +1,6 @@
{
"name": "@auth/mikro-orm-adapter",
"version": "1.0.0",
"version": "1.0.1",
"description": "MikroORM adapter for Auth.js",
"homepage": "https://authjs.dev",
"repository": "https://github.com/nextauthjs/next-auth",

View File

@@ -24,7 +24,7 @@ import type { Adapter } from "@auth/core/adapters"
import { MikroORM, wrap } from "@mikro-orm/core"
import * as defaultEntities from "./lib/entities"
import * as defaultEntities from "./lib/entities.js"
export { defaultEntities }

View File

@@ -1,6 +1,6 @@
{
"name": "@auth/prisma-adapter",
"version": "1.0.0",
"version": "1.0.1",
"description": "Prisma adapter for Auth.js",
"homepage": "https://authjs.dev/reference/adapter/prisma",
"repository": "https://github.com/nextauthjs/next-auth",

View File

@@ -21,7 +21,7 @@ import type { Adapter, AdapterAccount } from "@auth/core/adapters"
/**
* ## Setup
*
* Add this adapter to your `pages/api/[...nextauth].js` next-auth configuration object:
* Add this adapter to your `pages/api/auth/[...nextauth].js` next-auth configuration object:
*
* ```js title="pages/api/auth/[...nextauth].js"
* import NextAuth from "next-auth"

View File

@@ -1,6 +1,6 @@
{
"name": "@auth/core",
"version": "0.9.0",
"version": "0.10.0",
"description": "Authentication for the Web.",
"keywords": [
"authentication",

View File

@@ -223,7 +223,7 @@ export interface Adapter {
getUserByAccount?(
providerAccountId: Pick<AdapterAccount, "provider" | "providerAccountId">
): Awaitable<AdapterUser | null>
updateUser?(user: Partial<AdapterUser>): Awaitable<AdapterUser>
updateUser?(user: Partial<AdapterUser> & Pick<AdapterUser, 'id'>): Awaitable<AdapterUser>
/** @todo This method is currently not invoked yet. */
deleteUser?(
userId: string

View File

@@ -1,13 +1,14 @@
import { createHash, randomString } from "../web.js"
import { createHash, randomString, toRequest } from "../web.js"
import type { InternalOptions } from "../../types.js"
import type { InternalOptions, RequestInternal } from "../../types.js"
/**
* Starts an e-mail login flow, by generating a token,
* and sending it to the user's e-mail (with the help of a DB adapter)
*/
export default async function email(
identifier: string,
options: InternalOptions<"email">
options: InternalOptions<"email">,
request: RequestInternal
): Promise<string> {
const { url, adapter, provider, callbackUrl, theme } = options
const token =
@@ -31,6 +32,7 @@ export default async function email(
url: _url,
provider,
theme,
request: toRequest(request),
}),
// @ts-expect-error -- Verified in `assertConfig`.
adapter.createVerificationToken?.({

View File

@@ -137,8 +137,7 @@ export async function AuthInternal<
case "signin":
if ((csrfDisabled || options.csrfTokenVerified) && options.provider) {
const signin = await routes.signin(
request.query,
request.body,
request,
options
)
if (signin.cookies) cookies.push(...signin.cookies)

View File

@@ -122,7 +122,7 @@ export async function handleOAuth(
throw new Error("TODO: Handle www-authenticate challenges as needed")
}
let profile: Profile
let profile: Profile = {}
let tokens: TokenSet & Pick<Account, "expires_at">
if (provider.type === "oidc") {
@@ -153,7 +153,8 @@ export async function handleOAuth(
}
if (userinfo?.request) {
profile = await userinfo.request({ tokens, provider })
const _profile = await userinfo.request({ tokens, provider })
if (_profile instanceof Object) profile = _profile
} else if (userinfo?.url) {
const userinfoResponse = await o.userInfoRequest(
as,

View File

@@ -16,10 +16,10 @@ import type {
* For Email, sends an email with a sign in link.
*/
export async function signin(
query: RequestInternal["query"],
body: RequestInternal["body"],
request: RequestInternal,
options: InternalOptions<"oauth" | "oidc" | "email">
): Promise<ResponseInternal> {
const { query, body } = request
const { url, logger, provider } = options
try {
if (provider.type === "oauth" || provider.type === "oidc") {
@@ -48,7 +48,7 @@ export async function signin(
if (unauthorizedOrError) return unauthorizedOrError
const redirect = await emailSignin(email, options)
const redirect = await emailSignin(email, options, request)
return { redirect }
}
return { redirect: `${url}/signin` }

View File

@@ -72,6 +72,17 @@ export async function toInternalRequest(
}
}
export function toRequest(request: RequestInternal): Request {
return new Request(request.url, {
headers: request.headers,
method: request.method,
body:
request.method === "POST"
? JSON.stringify(request.body ?? {})
: undefined,
})
}
export function toResponse(res: ResponseInternal): Response {
const headers = new Headers(res.headers)

View File

@@ -131,6 +131,11 @@ export default function AzureAD<P extends AzureADProfile>(
name: "Azure Active Directory",
type: "oidc",
wellKnown: `${rest.issuer}}/.well-known/openid-configuration?appid=${options.clientId}`,
authorization: {
params: {
scope: 'openid profile email User.Read',
},
},
async profile(profile, tokens) {
// https://docs.microsoft.com/en-us/graph/api/profilephoto-get?view=graph-rest-1.0#examples
const response = await fetch(

View File

@@ -20,7 +20,7 @@ export interface BoxyHQSAMLProfile extends Record<string, any> {
/**
* Add BoxyHQ SAML login to your page.
*
* BoxyHQ SAML is an open source service that handles the SAML login flow as an OAuth 2.0 flow, abstracting away all the complexities of the SAML protocol.
* BoxyHQ SAML is an open source service that handles the SAML SSO login flow as an OAuth 2.0 flow, abstracting away all the complexities of the SAML protocol. Enable Enterprise single-sign-on in your app with ease.
*
* You can deploy BoxyHQ SAML as a separate service or embed it into your app using our NPM library. [Check out the documentation for more details](https://boxyhq.com/docs/jackson/deploy)
*
@@ -32,13 +32,38 @@ export interface BoxyHQSAMLProfile extends Record<string, any> {
* ```
*
* #### Configuration
*
* For OAuth 2.0 Flow:
*```js
* import Auth from "@auth/core"
* import BoxyHQ from "@auth/core/providers/boxyhq-saml"
*
* const request = new Request(origin)
* const response = await Auth(request, {
* providers: [BoxyHQ({ clientId: BOXYHQ_SAML_CLIENT_ID, clientSecret: BOXYHQ_SAML_CLIENT_SECRET. issuer: BOXYHQ_SAML_ISSUER })],
* providers: [BoxyHQ({
* authorization: { params: { scope: "" } }, // This is needed for OAuth 2.0 flow, otherwise default to openid
* clientId: BOXYHQ_SAML_CLIENT_ID,
* clientSecret: BOXYHQ_SAML_CLIENT_SECRET,
* issuer: BOXYHQ_SAML_ISSUER
* })],
* })
* ```
* For OIDC Flow:
*
*```js
* import Auth from "@auth/core"
* import BoxyHQ from "@auth/core/providers/boxyhq-saml"
*
* const request = new Request(origin)
* const response = await Auth(request, {
* providers: [BoxyHQ({
* id: "boxyhq-saml-oidc",
* wellKnown: `http://localhost:5225/.well-known/openid-configuration`,
* authorization: { params: { scope: "openid email" } },
* clientId: BOXYHQ_SAML_CLIENT_ID,
* clientSecret: BOXYHQ_SAML_CLIENT_SECRET,
* issuer: BOXYHQ_SAML_ISSUER
* })],
* })
* ```
*

View File

@@ -13,17 +13,25 @@
import type { OIDCConfig, OIDCUserConfig } from "./index.js"
/** The returned user profile from Descope when using the profile callback. */
/** The returned user profile from Descope when using the profile callback.
* [See Load User](https://docs.descope.com/api/openapi/usermanagement/operation/LoadUser/)
*/
export interface DescopeProfile {
/** The user Descope ID */
/** The user's unique Descope ID */
sub: string
/** The user's name */
name: string
/** The user's email */
email: string
/** A boolean indicating if the user's email is verified */
email_verified: boolean
/** The user's phone number */
phone_number: string
/** A boolean indicating if the user's phone number is verified */
phone_number_verified: boolean
/** The user's picture */
picture: string
/** Custom user's attributes */
/** The user's custom attributes */
[claim: string]: unknown
}
@@ -97,7 +105,7 @@ export default function Descope(
id: "descope",
name: "Descope",
type: "oidc",
clientId: `https://api.descope.com/${config.clientId}`,
issuer: `https://api.descope.com/${config.clientId}`,
style: {
logo: "/descope.svg",
logoDark: "/descope.svg",

View File

@@ -1,9 +1,17 @@
import { createTransport } from "nodemailer"
import type { CommonProviderOptions } from "./index.js"
import type { Options as SMTPTransportOptions } from "nodemailer/lib/smtp-transport"
import type { Awaitable, Theme } from "../types.js"
import { Transport, TransportOptions, createTransport } from "nodemailer"
import * as JSONTransport from "nodemailer/lib/json-transport/index.js"
import * as SendmailTransport from "nodemailer/lib/sendmail-transport/index.js"
import * as SESTransport from "nodemailer/lib/ses-transport/index.js"
import * as SMTPTransport from "nodemailer/lib/smtp-transport/index.js"
import * as SMTPPool from "nodemailer/lib/smtp-pool/index.js"
import * as StreamTransport from "nodemailer/lib/stream-transport/index.js"
// TODO: Make use of https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html for the string
type AllTransportOptions = string | SMTPTransport | SMTPTransport.Options | SMTPPool | SMTPPool.Options | SendmailTransport | SendmailTransport.Options | StreamTransport | StreamTransport.Options | JSONTransport | JSONTransport.Options | SESTransport | SESTransport.Options | Transport<any> | TransportOptions
export interface SendVerificationRequestParams {
identifier: string
url: string
@@ -11,6 +19,7 @@ export interface SendVerificationRequestParams {
provider: EmailConfig
token: string
theme: Theme
request: Request
}
/**
@@ -26,10 +35,9 @@ export interface SendVerificationRequestParams {
*
* [Custom email service with Auth.js](https://authjs.dev/guides/providers/email#custom-email-service)
*/
export interface EmailConfig extends CommonProviderOptions {
type: "email"
// TODO: Make use of https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html
server?: string | SMTPTransportOptions
export interface EmailUserConfig {
server?: AllTransportOptions
type?: "email"
/** @default `"Auth.js <no-reply@authjs.dev>"` */
from?: string
/**
@@ -40,7 +48,7 @@ export interface EmailConfig extends CommonProviderOptions {
*/
maxAge?: number
/** [Documentation](https://authjs.dev/guides/providers/email#customizing-emails) */
sendVerificationRequest: (
sendVerificationRequest?: (
params: SendVerificationRequestParams
) => Awaitable<void>
/**
@@ -77,24 +85,49 @@ export interface EmailConfig extends CommonProviderOptions {
normalizeIdentifier?: (identifier: string) => string
}
export interface EmailConfig extends CommonProviderOptions {
// defaults
id: "email"
type: "email"
name: "Email"
server: AllTransportOptions
from: string
maxAge: number
sendVerificationRequest: (
params: SendVerificationRequestParams
) => Awaitable<void>
/**
* This is copied into EmailConfig in parseProviders() don't use elsewhere
*/
options: EmailUserConfig
// user options
// TODO figure out a better way than copying from EmailUserConfig
secret?: string
generateVerificationToken?: () => Awaitable<string>
normalizeIdentifier?: (identifier: string) => string
}
// TODO: Rename to Token provider
// when started working on https://github.com/nextauthjs/next-auth/discussions/1465
export type EmailProviderType = "email"
/**
/**
* ## Overview
* The Email provider uses email to send "magic links" that can be used to sign in, you will likely have seen these if you have used services like Slack before.
*
*
* Adding support for signing in via email in addition to one or more OAuth services provides a way for users to sign in if they lose access to their OAuth account (e.g. if it is locked or deleted).
*
*
* The Email provider can be used in conjunction with (or instead of) one or more OAuth providers.
* ### How it works
*
*
* On initial sign in, a **Verification Token** is sent to the email address provided. By default this token is valid for 24 hours. If the Verification Token is used within that time (i.e. by clicking on the link in the email) an account is created for the user and they are signed in.
*
*
*
*
* If someone provides the email address of an _existing account_ when signing in, an email is sent and they are signed into the account associated with that email address when they follow the link in the email.
*
*
* :::tip
* The Email Provider can be used with both JSON Web Tokens and database sessions, but you **must** configure a database to use it. It is not possible to enable email sign in without using a database.
* :::
@@ -103,20 +136,20 @@ export type EmailProviderType = "email"
* 1. NextAuth.js does not include `nodemailer` as a dependency, so you'll need to install it yourself if you want to use the Email Provider. Run `npm install nodemailer` or `yarn add nodemailer`.
* 2. You will need an SMTP account; ideally for one of the [services known to work with `nodemailer`](https://community.nodemailer.com/2-0-0-beta/setup-smtp/well-known-services/).
* 3. There are two ways to configure the SMTP server connection.
*
*
* You can either use a connection string or a `nodemailer` configuration object.
*
*
* 3.1 **Using a connection string**
*
*
* Create an `.env` file to the root of your project and add the connection string and email address.
*
*
* ```js title=".env" {1}
* EMAIL_SERVER=smtp://username:password@smtp.example.com:587
* EMAIL_FROM=noreply@example.com
* ```
*
*
* Now you can add the email provider like this:
*
*
* ```js {3} title="pages/api/auth/[...nextauth].js"
* import EmailProvider from "next-auth/providers/email";
* ...
@@ -127,11 +160,11 @@ export type EmailProviderType = "email"
* }),
* ],
* ```
*
*
* 3.2 **Using a configuration object**
*
*
* In your `.env` file in the root of your project simply add the configuration object options individually:
*
*
* ```js title=".env"
* EMAIL_SERVER_USER=username
* EMAIL_SERVER_PASSWORD=password
@@ -139,9 +172,9 @@ export type EmailProviderType = "email"
* EMAIL_SERVER_PORT=587
* EMAIL_FROM=noreply@example.com
* ```
*
*
* Now you can add the provider settings to the NextAuth.js options object in the Email Provider.
*
*
* ```js title="pages/api/auth/[...nextauth].js"
* import EmailProvider from "next-auth/providers/email";
* ...
@@ -159,19 +192,19 @@ export type EmailProviderType = "email"
* }),
* ],
* ```
*
*
* 4. Do not forget to setup one of the database [adapters](https://authjs.dev/reference/adapters) for storing the Email verification token.
*
*
* 5. You can now sign in with an email address at `/api/auth/signin`.
*
*
* A user account (i.e. an entry in the Users table) will not be created for the user until the first time they verify their email address. If an email address is already associated with an account, the user will be signed in to that account when they use the link in the email.
*
*
* ## Customizing emails
*
*
* You can fully customize the sign in email that is sent by passing a custom function as the `sendVerificationRequest` option to `EmailProvider()`.
*
*
* e.g.
*
*
* ```js {3} title="pages/api/auth/[...nextauth].js"
* import EmailProvider from "next-auth/providers/email";
* ...
@@ -189,12 +222,12 @@ export type EmailProviderType = "email"
* }),
* ]
* ```
*
*
* The following code shows the complete source for the built-in `sendVerificationRequest()` method:
*
*
* ```js
* import { createTransport } from "nodemailer"
*
*
* async function sendVerificationRequest(params) {
* const { identifier, url, provider, theme } = params
* const { host } = new URL(url)
@@ -212,12 +245,12 @@ export type EmailProviderType = "email"
* throw new Error(`Email(s) (${failed.join(", ")}) could not be sent`)
* }
* }
*
*
* function html(params: { url: string; host: string; theme: Theme }) {
* const { url, host, theme } = params
*
*
* const escapedHost = host.replace(/\./g, "&#8203;.")
*
*
* const brandColor = theme.brandColor || "#346df1"
* const color = {
* background: "#f9f9f9",
@@ -227,7 +260,7 @@ export type EmailProviderType = "email"
* buttonBorder: brandColor,
* buttonText: theme.buttonText || "#fff",
* }
*
*
* return `
* <body style="background: ${color.background};">
* <table width="100%" border="0" cellspacing="20" cellpadding="0"
@@ -260,21 +293,21 @@ export type EmailProviderType = "email"
* </body>
* `
* }
*
*
* // Email Text body (fallback for email clients that don't render HTML, e.g. feature phones)
* function text({ url, host }: { url: string; host: string }) {
* return `Sign in to ${host}\n${url}\n\n`
* }
* ```
*
*
* :::tip
* If you want to generate great looking email client compatible HTML with React, check out https://mjml.io
* :::
*
*
* ## Customizing the Verification Token
*
*
* By default, we are generating a random verification token. You can define a `generateVerificationToken` method in your provider options if you want to override it:
*
*
* ```js title="pages/api/auth/[...nextauth].js"
* providers: [
* EmailProvider({
@@ -284,9 +317,9 @@ export type EmailProviderType = "email"
* })
* ],
* ```
*
*
* ## Normalizing the email address
*
*
* By default, Auth.js will normalize the email address. It treats values as case-insensitive (which is technically not compliant to the [RFC 2821 spec](https://datatracker.ietf.org/doc/html/rfc2821), but in practice this causes more problems than it solves, eg. when looking up users by e-mail from databases.) and also removes any secondary email address that was passed in as a comma-separated list. You can apply your own normalization via the `normalizeIdentifier` method on the `EmailProvider`. The following example shows the default behavior:
* ```ts
* EmailProvider({
@@ -299,7 +332,7 @@ export type EmailProviderType = "email"
* // but we remove it on the domain part
* domain = domain.split(",")[0]
* return `${local}@${domain}`
*
*
* // You can also throw an error, which will redirect the user
* // to the sign-in page with error=EmailSignin in the URL
* // if (identifier.split("@").length > 2) {
@@ -308,12 +341,12 @@ export type EmailProviderType = "email"
* },
* })
* ```
*
*
* :::warning
* Always make sure this returns a single e-mail address, even if multiple ones were passed in.
* :::
*/
export default function Email(config: EmailConfig): EmailConfig {
export default function Email(config: EmailUserConfig): EmailConfig {
return {
id: "email",
type: "email",
@@ -337,7 +370,6 @@ export default function Email(config: EmailConfig): EmailConfig {
throw new Error(`Email (${failed.join(", ")}) could not be sent`)
}
},
// @ts-expect-error
options: config,
}
}

View File

@@ -31,7 +31,7 @@ type EndpointRequest<C, R, P> = (
callbackUrl: string
}
}
) => Awaitable<R>
) => Awaitable<R> | void
/** Gives granular control of the request to the given endpoint */
interface AdvancedEndpointHandler<P extends UrlParams, C, R> {

View File

@@ -1,6 +1,6 @@
{
"name": "@auth/sveltekit",
"version": "0.3.3",
"version": "0.3.6",
"description": "Authentication for SvelteKit.",
"keywords": [
"authentication",
@@ -48,7 +48,7 @@
"@auth/core": "workspace:*"
},
"peerDependencies": {
"svelte": "^3.54.0",
"svelte": "^3.54.0 || ^4.0.0",
"@sveltejs/kit": "^1.0.0"
},
"type": "module",

View File

@@ -211,12 +211,13 @@ import type { AuthAction, AuthConfig, Session } from "@auth/core/types"
export async function getSession(
req: Request,
config: AuthConfig
config: SvelteKitAuthConfig
): ReturnType<App.Locals["getSession"]> {
config.secret ??= env.AUTH_SECRET
config.trustHost ??= true
const url = new URL("/api/auth/session", req.url)
const prefix = config.prefix ?? "/auth"
const url = new URL(prefix + "/session", req.url)
const request = new Request(url, { headers: req.headers })
const response = await Auth(request, config)

View File

@@ -173,7 +173,7 @@ export type WithAuthArgs =
/**
* Middleware that checks if the user is authenticated/authorized.
* If if they aren't, they will be redirected to the login page.
* If they aren't, they will be redirected to the login page.
* Otherwise, continue.
*
* @example

7654
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
packages:
- "packages/*"
- "apps/dev/*"
- "apps/playgrounds/*"
- "docs"

View File

@@ -3,7 +3,8 @@
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**/*", "*.js", "*.d.ts", "*.d.ts.map"]
"outputs": ["dist/**/*", "*.js", "*.d.ts", "*.d.ts.map"],
"outputMode": "new-only"
},
"next-auth#build": {
"dependsOn": ["^build"],
@@ -17,7 +18,8 @@
"react/**",
"*.js",
"*.d.ts"
]
],
"outputMode": "new-only"
},
"@auth/core#build": {
"dependsOn": ["^build"],
@@ -29,11 +31,13 @@
"*.d.ts.map",
"src/lib/pages/styles.ts",
"src/providers/oauth-types.ts"
]
],
"outputMode": "new-only"
},
"@auth/sveltekit#build": {
"dependsOn": ["^build"],
"outputs": [".svelte-kit/**", "client.*", "index.*"]
"outputs": [".svelte-kit/**", "client.*", "index.*"],
"outputMode": "new-only"
},
"clean": {
"cache": false
@@ -42,7 +46,7 @@
"cache": false
},
"test": {
"outputs": []
"outputMode": "new-only"
},
"e2e": {
"outputs": ["playwright-report/**"]