@auth/express
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -24,20 +24,5 @@ /** | ||
* | ||
* // Make sure to use these body parsers so Auth.js can receive data from the client | ||
* app.use(express.json()) | ||
* app.use(express.urlencoded({ extended: true })) | ||
* | ||
* // If app is served through a proxy, trust the proxy to allow HTTPS protocol to be detected | ||
* app.use('trust proxy') | ||
* | ||
* app.use( | ||
* "/api/auth/*", | ||
* ExpressAuth({ | ||
* providers: [ | ||
* GitHub({ | ||
* clientId: process.env.GITHUB_ID, | ||
* clientSecret: process.env.GITHUB_SECRET, | ||
* }), | ||
* ], | ||
* }) | ||
* ) | ||
* app.use("/auth/*", ExpressAuth({ providers: [ GitHub ] })) | ||
* ``` | ||
@@ -53,3 +38,3 @@ * | ||
* ``` | ||
* [origin]/api/auth/callback/[provider] | ||
* [origin]/auth/callback/[provider] | ||
* ``` | ||
@@ -142,9 +127,16 @@ * | ||
*/ | ||
import type { AuthConfig, Session } from "@auth/core/types"; | ||
import { Request as ExpressRequest, Response as ExpressResponse } from "express"; | ||
/// <reference types="node" /> | ||
import type { AuthAction, AuthConfig, Session } from "@auth/core/types"; | ||
import * as e from "express"; | ||
import type { IncomingHttpHeaders } from "http"; | ||
export type { Account, DefaultSession, Profile, Session, User, } from "@auth/core/types"; | ||
declare function ExpressAuthHandler(authConfig: Omit<AuthConfig, "raw">): (req: ExpressRequest, res: ExpressResponse) => Promise<void>; | ||
export declare function ExpressAuth(config: AuthConfig): ReturnType<typeof ExpressAuthHandler>; | ||
export declare function ExpressAuth(config: Omit<AuthConfig, "raw">): (req: e.Request, res: e.Response, next: e.NextFunction) => Promise<void>; | ||
export type GetSessionResult = Promise<Session | null>; | ||
export declare function getSession(req: ExpressRequest, options: Omit<AuthConfig, "raw">): GetSessionResult; | ||
export declare function getSession(req: e.Request, config: Omit<AuthConfig, "raw">): GetSessionResult; | ||
export declare function setEnvDefaults(config: AuthConfig): void; | ||
/** | ||
* Extract the origin and base path from either the `AUTH_URL` environment variable, | ||
* or the request's headers and the {@link AuthConfig.basePath} option. | ||
*/ | ||
export declare function createActionURL(action: AuthAction, protocol: string, headers: IncomingHttpHeaders, basePath?: string): URL; | ||
//# sourceMappingURL=index.d.ts.map |
108
index.js
@@ -24,20 +24,5 @@ /** | ||
* | ||
* // Make sure to use these body parsers so Auth.js can receive data from the client | ||
* app.use(express.json()) | ||
* app.use(express.urlencoded({ extended: true })) | ||
* | ||
* // If app is served through a proxy, trust the proxy to allow HTTPS protocol to be detected | ||
* app.use('trust proxy') | ||
* | ||
* app.use( | ||
* "/api/auth/*", | ||
* ExpressAuth({ | ||
* providers: [ | ||
* GitHub({ | ||
* clientId: process.env.GITHUB_ID, | ||
* clientSecret: process.env.GITHUB_SECRET, | ||
* }), | ||
* ], | ||
* }) | ||
* ) | ||
* app.use("/auth/*", ExpressAuth({ providers: [ GitHub ] })) | ||
* ``` | ||
@@ -53,3 +38,3 @@ * | ||
* ``` | ||
* [origin]/api/auth/callback/[provider] | ||
* [origin]/auth/callback/[provider] | ||
* ``` | ||
@@ -143,26 +128,24 @@ * | ||
import { Auth } from "@auth/core"; | ||
import * as e from "express"; | ||
import { toWebRequest, toExpressResponse } from "./lib/index.js"; | ||
function ExpressAuthHandler(authConfig) { | ||
return async (req, res) => { | ||
const request = toWebRequest(req); | ||
const response = await Auth(request, authConfig); | ||
await toExpressResponse(response, res); | ||
export function ExpressAuth(config) { | ||
return async (req, res, next) => { | ||
e.json()(req, res, async (err) => { | ||
if (err) | ||
return next(err); | ||
e.urlencoded({ extended: true })(req, res, async (err) => { | ||
if (err) | ||
return next(err); | ||
config.basePath = getBasePath(req); | ||
setEnvDefaults(config); | ||
await toExpressResponse(await Auth(toWebRequest(req), config), res); | ||
next(); | ||
}); | ||
}); | ||
}; | ||
} | ||
export function ExpressAuth(config) { | ||
const { ...authOptions } = config; | ||
authOptions.secret ?? (authOptions.secret = process.env.AUTH_SECRET); | ||
authOptions.redirectProxyUrl ?? (authOptions.redirectProxyUrl = process.env.AUTH_REDIRECT_PROXY_URL); | ||
authOptions.trustHost ?? (authOptions.trustHost = !!(process.env.AUTH_TRUST_HOST ?? | ||
process.env.VERCEL ?? | ||
process.env.NODE_ENV !== "production")); | ||
const handler = ExpressAuthHandler(authOptions); | ||
return handler; | ||
} | ||
export async function getSession(req, options) { | ||
options.secret ?? (options.secret = process.env.AUTH_SECRET); | ||
options.trustHost ?? (options.trustHost = true); | ||
const request = toWebRequest(req); | ||
const url = new URL("/api/auth/session", request.url); | ||
const response = await Auth(new Request(url, { headers: request.headers }), options); | ||
export async function getSession(req, config) { | ||
setEnvDefaults(config); | ||
const url = createActionURL("session", req.protocol.toString(), req.headers, config.basePath); | ||
const response = await Auth(new Request(url, { headers: { cookie: req.headers.cookie ?? "" } }), config); | ||
const { status = 200 } = response; | ||
@@ -176,1 +159,50 @@ const data = await response.json(); | ||
} | ||
export function setEnvDefaults(config) { | ||
config.secret ?? (config.secret = process.env.AUTH_SECRET); | ||
try { | ||
const url = process.env.AUTH_URL; | ||
if (url) | ||
config.basePath = new URL(url).pathname; | ||
} | ||
catch { | ||
} | ||
finally { | ||
config.basePath ?? (config.basePath = "/auth"); | ||
} | ||
config.trustHost ?? (config.trustHost = !!(process.env.AUTH_URL ?? | ||
process.env.AUTH_TRUST_HOST ?? | ||
process.env.VERCEL ?? | ||
process.env.NODE_ENV !== "production")); | ||
config.redirectProxyUrl ?? (config.redirectProxyUrl = process.env.AUTH_REDIRECT_PROXY_URL); | ||
config.providers = config.providers.map((p) => { | ||
const finalProvider = typeof p === "function" ? p({}) : p; | ||
const ID = finalProvider.id.toUpperCase(); | ||
if (finalProvider.type === "oauth" || finalProvider.type === "oidc") { | ||
finalProvider.clientId ?? (finalProvider.clientId = process.env[`AUTH_${ID}_ID`]); | ||
finalProvider.clientSecret ?? (finalProvider.clientSecret = process.env[`AUTH_${ID}_SECRET`]); | ||
if (finalProvider.type === "oidc") { | ||
finalProvider.issuer ?? (finalProvider.issuer = process.env[`AUTH_${ID}_ISSUER`]); | ||
} | ||
} | ||
else if (finalProvider.type === "email") { | ||
finalProvider.apiKey ?? (finalProvider.apiKey = process.env[`AUTH_${ID}_KEY`]); | ||
} | ||
return finalProvider; | ||
}); | ||
} | ||
/** | ||
* Extract the origin and base path from either the `AUTH_URL` environment variable, | ||
* or the request's headers and the {@link AuthConfig.basePath} option. | ||
*/ | ||
export function createActionURL(action, protocol, headers, basePath) { | ||
let url = process.env.AUTH_URL; | ||
if (!url) { | ||
const host = headers["x-forwarded-host"] ?? headers.host; | ||
const proto = headers["x-forwarded-proto"] ?? protocol; | ||
url = `${proto === "http" ? "http" : "https"}://${host}${basePath}`; | ||
} | ||
return new URL(`${url.replace(/\/$/, "")}/${action}`); | ||
} | ||
function getBasePath(req) { | ||
return req.baseUrl.split(req.params[0])[0].replace(/\/$/, ""); | ||
} |
{ | ||
"name": "@auth/express", | ||
"description": "Authentication for Express.", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"type": "module", | ||
@@ -21,2 +21,5 @@ "files": [ | ||
}, | ||
"./adapters": { | ||
"types": "./adapters.d.ts" | ||
}, | ||
"./providers/*": { | ||
@@ -32,3 +35,3 @@ "types": "./providers/*.d.ts", | ||
"dependencies": { | ||
"@auth/core": "0.21.0" | ||
"@auth/core": "0.23.0" | ||
}, | ||
@@ -35,0 +38,0 @@ "devDependencies": { |
135
src/index.ts
@@ -24,20 +24,5 @@ /** | ||
* | ||
* // Make sure to use these body parsers so Auth.js can receive data from the client | ||
* app.use(express.json()) | ||
* app.use(express.urlencoded({ extended: true })) | ||
* | ||
* // If app is served through a proxy, trust the proxy to allow HTTPS protocol to be detected | ||
* app.use('trust proxy') | ||
* | ||
* app.use( | ||
* "/api/auth/*", | ||
* ExpressAuth({ | ||
* providers: [ | ||
* GitHub({ | ||
* clientId: process.env.GITHUB_ID, | ||
* clientSecret: process.env.GITHUB_SECRET, | ||
* }), | ||
* ], | ||
* }) | ||
* ) | ||
* app.use("/auth/*", ExpressAuth({ providers: [ GitHub ] })) | ||
* ``` | ||
@@ -53,3 +38,3 @@ * | ||
* ``` | ||
* [origin]/api/auth/callback/[provider] | ||
* [origin]/auth/callback/[provider] | ||
* ``` | ||
@@ -144,5 +129,6 @@ * | ||
import { Auth } from "@auth/core" | ||
import type { AuthConfig, Session } from "@auth/core/types" | ||
import { Request as ExpressRequest, Response as ExpressResponse } from "express" | ||
import type { AuthAction, AuthConfig, Session } from "@auth/core/types" | ||
import * as e from "express" | ||
import { toWebRequest, toExpressResponse } from "./lib/index.js" | ||
import type { IncomingHttpHeaders } from "http" | ||
@@ -157,42 +143,34 @@ export type { | ||
function ExpressAuthHandler(authConfig: Omit<AuthConfig, "raw">) { | ||
return async (req: ExpressRequest, res: ExpressResponse) => { | ||
const request = toWebRequest(req) | ||
const response = await Auth(request, authConfig) | ||
await toExpressResponse(response, res) | ||
export function ExpressAuth(config: Omit<AuthConfig, "raw">) { | ||
return async (req: e.Request, res: e.Response, next: e.NextFunction) => { | ||
e.json()(req, res, async (err) => { | ||
if (err) return next(err) | ||
e.urlencoded({ extended: true })(req, res, async (err) => { | ||
if (err) return next(err) | ||
config.basePath = getBasePath(req) | ||
setEnvDefaults(config) | ||
await toExpressResponse(await Auth(toWebRequest(req), config), res) | ||
next() | ||
}) | ||
}) | ||
} | ||
} | ||
export function ExpressAuth( | ||
config: AuthConfig | ||
): ReturnType<typeof ExpressAuthHandler> { | ||
const { ...authOptions } = config | ||
authOptions.secret ??= process.env.AUTH_SECRET | ||
authOptions.redirectProxyUrl ??= process.env.AUTH_REDIRECT_PROXY_URL | ||
authOptions.trustHost ??= !!( | ||
process.env.AUTH_TRUST_HOST ?? | ||
process.env.VERCEL ?? | ||
process.env.NODE_ENV !== "production" | ||
) | ||
const handler = ExpressAuthHandler(authOptions) | ||
return handler | ||
} | ||
export type GetSessionResult = Promise<Session | null> | ||
export async function getSession( | ||
req: ExpressRequest, | ||
options: Omit<AuthConfig, "raw"> | ||
req: e.Request, | ||
config: Omit<AuthConfig, "raw"> | ||
): GetSessionResult { | ||
options.secret ??= process.env.AUTH_SECRET | ||
options.trustHost ??= true | ||
setEnvDefaults(config) | ||
const url = createActionURL( | ||
"session", | ||
req.protocol.toString(), | ||
req.headers, | ||
config.basePath | ||
) | ||
const request = toWebRequest(req) | ||
const url = new URL("/api/auth/session", request.url) | ||
const response = await Auth( | ||
new Request(url, { headers: request.headers }), | ||
options | ||
new Request(url, { headers: { cookie: req.headers.cookie ?? "" } }), | ||
config | ||
) | ||
@@ -208,1 +186,58 @@ | ||
} | ||
export function setEnvDefaults(config: AuthConfig) { | ||
config.secret ??= process.env.AUTH_SECRET | ||
try { | ||
const url = process.env.AUTH_URL | ||
if (url) config.basePath = new URL(url).pathname | ||
} catch { | ||
} finally { | ||
config.basePath ??= "/auth" | ||
} | ||
config.trustHost ??= !!( | ||
process.env.AUTH_URL ?? | ||
process.env.AUTH_TRUST_HOST ?? | ||
process.env.VERCEL ?? | ||
process.env.NODE_ENV !== "production" | ||
) | ||
config.redirectProxyUrl ??= process.env.AUTH_REDIRECT_PROXY_URL | ||
config.providers = config.providers.map((p) => { | ||
const finalProvider = typeof p === "function" ? p({}) : p | ||
const ID = finalProvider.id.toUpperCase() | ||
if (finalProvider.type === "oauth" || finalProvider.type === "oidc") { | ||
finalProvider.clientId ??= process.env[`AUTH_${ID}_ID`] | ||
finalProvider.clientSecret ??= process.env[`AUTH_${ID}_SECRET`] | ||
if (finalProvider.type === "oidc") { | ||
finalProvider.issuer ??= process.env[`AUTH_${ID}_ISSUER`] | ||
} | ||
} else if (finalProvider.type === "email") { | ||
finalProvider.apiKey ??= process.env[`AUTH_${ID}_KEY`] | ||
} | ||
return finalProvider | ||
}) | ||
} | ||
/** | ||
* Extract the origin and base path from either the `AUTH_URL` environment variable, | ||
* or the request's headers and the {@link AuthConfig.basePath} option. | ||
*/ | ||
export function createActionURL( | ||
action: AuthAction, | ||
protocol: string, | ||
headers: IncomingHttpHeaders, | ||
basePath?: string | ||
): URL { | ||
let url = process.env.AUTH_URL | ||
if (!url) { | ||
const host = headers["x-forwarded-host"] ?? headers.host | ||
const proto = headers["x-forwarded-proto"] ?? protocol | ||
url = `${proto === "http" ? "http" : "https"}://${host}${basePath}` | ||
} | ||
return new URL(`${url.replace(/\/$/, "")}/${action}`) | ||
} | ||
function getBasePath(req: e.Request) { | ||
return req.baseUrl.split(req.params[0])[0].replace(/\/$/, "") | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
64005
257
1058
13
+ Added@auth/core@0.23.0(transitive)
- Removed@auth/core@0.21.0(transitive)
Updated@auth/core@0.23.0