mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
Compare commits
9 Commits
@auth/svel
...
@auth/core
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e459d2d7e2 | ||
|
|
db1fd9007c | ||
|
|
0439fc5fc6 | ||
|
|
d0dd2ababc | ||
|
|
ba58d48dba | ||
|
|
a8d76ed440 | ||
|
|
3d7b8720db | ||
|
|
1e886b97bc | ||
|
|
ecb14ccecd |
@@ -112,6 +112,7 @@ providers: [
|
|||||||
identifier: email,
|
identifier: email,
|
||||||
url,
|
url,
|
||||||
provider: { server, from },
|
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 */
|
/* your function */
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@auth/dynamodb-adapter",
|
"name": "@auth/dynamodb-adapter",
|
||||||
"repository": "https://github.com/nextauthjs/next-auth",
|
"repository": "https://github.com/nextauthjs/next-auth",
|
||||||
"version": "1.0.0",
|
"version": "1.0.1",
|
||||||
"description": "AWS DynamoDB adapter for next-auth.",
|
"description": "AWS DynamoDB adapter for next-auth.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"next-auth",
|
"next-auth",
|
||||||
|
|||||||
@@ -265,9 +265,8 @@ export function DynamoDBAdapter(
|
|||||||
const data = await client.update({
|
const data = await client.update({
|
||||||
TableName,
|
TableName,
|
||||||
Key: {
|
Key: {
|
||||||
// next-auth type is incorrect it should be Partial<AdapterUser> & {id: string} instead of just Partial<AdapterUser>
|
[pk]: `USER#${user.id}`,
|
||||||
[pk]: `USER#${user.id as string}`,
|
[sk]: `USER#${user.id}`,
|
||||||
[sk]: `USER#${user.id as string}`,
|
|
||||||
},
|
},
|
||||||
UpdateExpression,
|
UpdateExpression,
|
||||||
ExpressionAttributeNames,
|
ExpressionAttributeNames,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@auth/core",
|
"name": "@auth/core",
|
||||||
"version": "0.9.0",
|
"version": "0.10.0",
|
||||||
"description": "Authentication for the Web.",
|
"description": "Authentication for the Web.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"authentication",
|
"authentication",
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ export interface Adapter {
|
|||||||
getUserByAccount?(
|
getUserByAccount?(
|
||||||
providerAccountId: Pick<AdapterAccount, "provider" | "providerAccountId">
|
providerAccountId: Pick<AdapterAccount, "provider" | "providerAccountId">
|
||||||
): Awaitable<AdapterUser | null>
|
): 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. */
|
/** @todo This method is currently not invoked yet. */
|
||||||
deleteUser?(
|
deleteUser?(
|
||||||
userId: string
|
userId: string
|
||||||
|
|||||||
@@ -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,
|
* 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)
|
* and sending it to the user's e-mail (with the help of a DB adapter)
|
||||||
*/
|
*/
|
||||||
export default async function email(
|
export default async function email(
|
||||||
identifier: string,
|
identifier: string,
|
||||||
options: InternalOptions<"email">
|
options: InternalOptions<"email">,
|
||||||
|
request: RequestInternal
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
const { url, adapter, provider, callbackUrl, theme } = options
|
const { url, adapter, provider, callbackUrl, theme } = options
|
||||||
const token =
|
const token =
|
||||||
@@ -31,6 +32,7 @@ export default async function email(
|
|||||||
url: _url,
|
url: _url,
|
||||||
provider,
|
provider,
|
||||||
theme,
|
theme,
|
||||||
|
request: toRequest(request),
|
||||||
}),
|
}),
|
||||||
// @ts-expect-error -- Verified in `assertConfig`.
|
// @ts-expect-error -- Verified in `assertConfig`.
|
||||||
adapter.createVerificationToken?.({
|
adapter.createVerificationToken?.({
|
||||||
|
|||||||
@@ -137,8 +137,7 @@ export async function AuthInternal<
|
|||||||
case "signin":
|
case "signin":
|
||||||
if ((csrfDisabled || options.csrfTokenVerified) && options.provider) {
|
if ((csrfDisabled || options.csrfTokenVerified) && options.provider) {
|
||||||
const signin = await routes.signin(
|
const signin = await routes.signin(
|
||||||
request.query,
|
request,
|
||||||
request.body,
|
|
||||||
options
|
options
|
||||||
)
|
)
|
||||||
if (signin.cookies) cookies.push(...signin.cookies)
|
if (signin.cookies) cookies.push(...signin.cookies)
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ import type {
|
|||||||
* For Email, sends an email with a sign in link.
|
* For Email, sends an email with a sign in link.
|
||||||
*/
|
*/
|
||||||
export async function signin(
|
export async function signin(
|
||||||
query: RequestInternal["query"],
|
request: RequestInternal,
|
||||||
body: RequestInternal["body"],
|
|
||||||
options: InternalOptions<"oauth" | "oidc" | "email">
|
options: InternalOptions<"oauth" | "oidc" | "email">
|
||||||
): Promise<ResponseInternal> {
|
): Promise<ResponseInternal> {
|
||||||
|
const { query, body } = request
|
||||||
const { url, logger, provider } = options
|
const { url, logger, provider } = options
|
||||||
try {
|
try {
|
||||||
if (provider.type === "oauth" || provider.type === "oidc") {
|
if (provider.type === "oauth" || provider.type === "oidc") {
|
||||||
@@ -48,7 +48,7 @@ export async function signin(
|
|||||||
|
|
||||||
if (unauthorizedOrError) return unauthorizedOrError
|
if (unauthorizedOrError) return unauthorizedOrError
|
||||||
|
|
||||||
const redirect = await emailSignin(email, options)
|
const redirect = await emailSignin(email, options, request)
|
||||||
return { redirect }
|
return { redirect }
|
||||||
}
|
}
|
||||||
return { redirect: `${url}/signin` }
|
return { redirect: `${url}/signin` }
|
||||||
|
|||||||
@@ -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 {
|
export function toResponse(res: ResponseInternal): Response {
|
||||||
const headers = new Headers(res.headers)
|
const headers = new Headers(res.headers)
|
||||||
|
|
||||||
|
|||||||
@@ -131,6 +131,11 @@ export default function AzureAD<P extends AzureADProfile>(
|
|||||||
name: "Azure Active Directory",
|
name: "Azure Active Directory",
|
||||||
type: "oidc",
|
type: "oidc",
|
||||||
wellKnown: `${rest.issuer}}/.well-known/openid-configuration?appid=${options.clientId}`,
|
wellKnown: `${rest.issuer}}/.well-known/openid-configuration?appid=${options.clientId}`,
|
||||||
|
authorization: {
|
||||||
|
params: {
|
||||||
|
scope: 'openid profile email User.Read',
|
||||||
|
},
|
||||||
|
},
|
||||||
async profile(profile, tokens) {
|
async profile(profile, tokens) {
|
||||||
// https://docs.microsoft.com/en-us/graph/api/profilephoto-get?view=graph-rest-1.0#examples
|
// https://docs.microsoft.com/en-us/graph/api/profilephoto-get?view=graph-rest-1.0#examples
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export interface BoxyHQSAMLProfile extends Record<string, any> {
|
|||||||
/**
|
/**
|
||||||
* Add BoxyHQ SAML login to your page.
|
* 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)
|
* 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
|
* #### Configuration
|
||||||
|
*
|
||||||
|
* For OAuth 2.0 Flow:
|
||||||
*```js
|
*```js
|
||||||
* import Auth from "@auth/core"
|
* import Auth from "@auth/core"
|
||||||
* import BoxyHQ from "@auth/core/providers/boxyhq-saml"
|
* import BoxyHQ from "@auth/core/providers/boxyhq-saml"
|
||||||
*
|
*
|
||||||
* const request = new Request(origin)
|
* const request = new Request(origin)
|
||||||
* const response = await Auth(request, {
|
* 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
|
||||||
|
* })],
|
||||||
* })
|
* })
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -13,17 +13,25 @@
|
|||||||
|
|
||||||
import type { OIDCConfig, OIDCUserConfig } from "./index.js"
|
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 {
|
export interface DescopeProfile {
|
||||||
/** The user Descope ID */
|
/** The user's unique Descope ID */
|
||||||
sub: string
|
sub: string
|
||||||
|
/** The user's name */
|
||||||
name: string
|
name: string
|
||||||
|
/** The user's email */
|
||||||
email: string
|
email: string
|
||||||
|
/** A boolean indicating if the user's email is verified */
|
||||||
email_verified: boolean
|
email_verified: boolean
|
||||||
|
/** The user's phone number */
|
||||||
phone_number: string
|
phone_number: string
|
||||||
|
/** A boolean indicating if the user's phone number is verified */
|
||||||
phone_number_verified: boolean
|
phone_number_verified: boolean
|
||||||
|
/** The user's picture */
|
||||||
picture: string
|
picture: string
|
||||||
/** Custom user's attributes */
|
/** The user's custom attributes */
|
||||||
[claim: string]: unknown
|
[claim: string]: unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +105,7 @@ export default function Descope(
|
|||||||
id: "descope",
|
id: "descope",
|
||||||
name: "Descope",
|
name: "Descope",
|
||||||
type: "oidc",
|
type: "oidc",
|
||||||
clientId: `https://api.descope.com/${config.clientId}`,
|
issuer: `https://api.descope.com/${config.clientId}`,
|
||||||
style: {
|
style: {
|
||||||
logo: "/descope.svg",
|
logo: "/descope.svg",
|
||||||
logoDark: "/descope.svg",
|
logoDark: "/descope.svg",
|
||||||
|
|||||||
@@ -1,9 +1,17 @@
|
|||||||
import { createTransport } from "nodemailer"
|
|
||||||
|
|
||||||
import type { CommonProviderOptions } from "./index.js"
|
import type { CommonProviderOptions } from "./index.js"
|
||||||
import type { Options as SMTPTransportOptions } from "nodemailer/lib/smtp-transport"
|
|
||||||
import type { Awaitable, Theme } from "../types.js"
|
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 {
|
export interface SendVerificationRequestParams {
|
||||||
identifier: string
|
identifier: string
|
||||||
url: string
|
url: string
|
||||||
@@ -11,6 +19,7 @@ export interface SendVerificationRequestParams {
|
|||||||
provider: EmailConfig
|
provider: EmailConfig
|
||||||
token: string
|
token: string
|
||||||
theme: Theme
|
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)
|
* [Custom email service with Auth.js](https://authjs.dev/guides/providers/email#custom-email-service)
|
||||||
*/
|
*/
|
||||||
export interface EmailConfig extends CommonProviderOptions {
|
export interface EmailUserConfig {
|
||||||
type: "email"
|
server?: AllTransportOptions
|
||||||
// TODO: Make use of https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html
|
type?: "email"
|
||||||
server?: string | SMTPTransportOptions
|
|
||||||
/** @default `"Auth.js <no-reply@authjs.dev>"` */
|
/** @default `"Auth.js <no-reply@authjs.dev>"` */
|
||||||
from?: string
|
from?: string
|
||||||
/**
|
/**
|
||||||
@@ -40,7 +48,7 @@ export interface EmailConfig extends CommonProviderOptions {
|
|||||||
*/
|
*/
|
||||||
maxAge?: number
|
maxAge?: number
|
||||||
/** [Documentation](https://authjs.dev/guides/providers/email#customizing-emails) */
|
/** [Documentation](https://authjs.dev/guides/providers/email#customizing-emails) */
|
||||||
sendVerificationRequest: (
|
sendVerificationRequest?: (
|
||||||
params: SendVerificationRequestParams
|
params: SendVerificationRequestParams
|
||||||
) => Awaitable<void>
|
) => Awaitable<void>
|
||||||
/**
|
/**
|
||||||
@@ -77,6 +85,31 @@ export interface EmailConfig extends CommonProviderOptions {
|
|||||||
normalizeIdentifier?: (identifier: string) => string
|
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
|
// TODO: Rename to Token provider
|
||||||
// when started working on https://github.com/nextauthjs/next-auth/discussions/1465
|
// when started working on https://github.com/nextauthjs/next-auth/discussions/1465
|
||||||
export type EmailProviderType = "email"
|
export type EmailProviderType = "email"
|
||||||
@@ -313,7 +346,7 @@ export type EmailProviderType = "email"
|
|||||||
* Always make sure this returns a single e-mail address, even if multiple ones were passed in.
|
* 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 {
|
return {
|
||||||
id: "email",
|
id: "email",
|
||||||
type: "email",
|
type: "email",
|
||||||
@@ -337,7 +370,6 @@ export default function Email(config: EmailConfig): EmailConfig {
|
|||||||
throw new Error(`Email (${failed.join(", ")}) could not be sent`)
|
throw new Error(`Email (${failed.join(", ")}) could not be sent`)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// @ts-expect-error
|
|
||||||
options: config,
|
options: config,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@auth/sveltekit",
|
"name": "@auth/sveltekit",
|
||||||
"version": "0.3.5",
|
"version": "0.3.6",
|
||||||
"description": "Authentication for SvelteKit.",
|
"description": "Authentication for SvelteKit.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"authentication",
|
"authentication",
|
||||||
|
|||||||
@@ -211,12 +211,13 @@ import type { AuthAction, AuthConfig, Session } from "@auth/core/types"
|
|||||||
|
|
||||||
export async function getSession(
|
export async function getSession(
|
||||||
req: Request,
|
req: Request,
|
||||||
config: AuthConfig
|
config: SvelteKitAuthConfig
|
||||||
): ReturnType<App.Locals["getSession"]> {
|
): ReturnType<App.Locals["getSession"]> {
|
||||||
config.secret ??= env.AUTH_SECRET
|
config.secret ??= env.AUTH_SECRET
|
||||||
config.trustHost ??= true
|
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 request = new Request(url, { headers: req.headers })
|
||||||
const response = await Auth(request, config)
|
const response = await Auth(request, config)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user