next-auth
Version:
Authentication for Next.js
322 lines (321 loc) • 11.3 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.AuthHandler = AuthHandler;
var _logger = _interopRequireWildcard(require("../utils/logger"));
var _detectOrigin = require("../utils/detect-origin");
var routes = _interopRequireWildcard(require("./routes"));
var _pages = _interopRequireDefault(require("./pages"));
var _init = require("./init");
var _assert = require("./lib/assert");
var _cookie = require("./lib/cookie");
var _cookie2 = require("cookie");
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
async function getBody(req) {
try {
return await req.json();
} catch (_unused) {}
}
async function toInternalRequest(req) {
var _headers$xForwarded2;
if (req instanceof Request) {
var _req$headers$get, _url$searchParams$get, _headers$xForwarded;
const url = new URL(req.url);
const nextauth = url.pathname.split("/").slice(3);
const headers = Object.fromEntries(req.headers);
const query = Object.fromEntries(url.searchParams);
query.nextauth = nextauth;
return {
action: nextauth[0],
method: req.method,
headers,
body: await getBody(req),
cookies: (0, _cookie2.parse)((_req$headers$get = req.headers.get("cookie")) !== null && _req$headers$get !== void 0 ? _req$headers$get : ""),
providerId: nextauth[1],
error: (_url$searchParams$get = url.searchParams.get("error")) !== null && _url$searchParams$get !== void 0 ? _url$searchParams$get : nextauth[1],
origin: (0, _detectOrigin.detectOrigin)((_headers$xForwarded = headers["x-forwarded-host"]) !== null && _headers$xForwarded !== void 0 ? _headers$xForwarded : headers.host, headers["x-forwarded-proto"]),
query
};
}
const {
headers
} = req;
const host = (_headers$xForwarded2 = headers === null || headers === void 0 ? void 0 : headers["x-forwarded-host"]) !== null && _headers$xForwarded2 !== void 0 ? _headers$xForwarded2 : headers === null || headers === void 0 ? void 0 : headers.host;
req.origin = (0, _detectOrigin.detectOrigin)(host, headers === null || headers === void 0 ? void 0 : headers["x-forwarded-proto"]);
return req;
}
async function AuthHandler(params) {
var _req$body$callbackUrl, _req$body, _req$query2, _req$body2;
const {
options: authOptions,
req: incomingRequest
} = params;
const req = await toInternalRequest(incomingRequest);
(0, _logger.setLogger)(authOptions.logger, authOptions.debug);
const assertionResult = (0, _assert.assertConfig)({
options: authOptions,
req
});
if (Array.isArray(assertionResult)) {
assertionResult.forEach(_logger.default.warn);
} else if (assertionResult instanceof Error) {
var _req$query;
_logger.default.error(assertionResult.code, assertionResult);
const htmlPages = ["signin", "signout", "error", "verify-request"];
if (!htmlPages.includes(req.action) || req.method !== "GET") {
const message = `There is a problem with the server configuration. Check the server logs for more information.`;
return {
status: 500,
headers: [{
key: "Content-Type",
value: "application/json"
}],
body: {
message
}
};
}
const {
pages,
theme
} = authOptions;
const authOnErrorPage = (pages === null || pages === void 0 ? void 0 : pages.error) && ((_req$query = req.query) === null || _req$query === void 0 || (_req$query = _req$query.callbackUrl) === null || _req$query === void 0 ? void 0 : _req$query.startsWith(pages.error));
if (!(pages !== null && pages !== void 0 && pages.error) || authOnErrorPage) {
if (authOnErrorPage) {
_logger.default.error("AUTH_ON_ERROR_PAGE_ERROR", new Error(`The error page ${pages === null || pages === void 0 ? void 0 : pages.error} should not require authentication`));
}
const render = (0, _pages.default)({
theme
});
return render.error({
error: "configuration"
});
}
return {
redirect: `${pages.error}?error=Configuration`
};
}
const {
action,
providerId,
error,
method = "GET"
} = req;
const {
options,
cookies
} = await (0, _init.init)({
authOptions,
action,
providerId,
origin: req.origin,
callbackUrl: (_req$body$callbackUrl = (_req$body = req.body) === null || _req$body === void 0 ? void 0 : _req$body.callbackUrl) !== null && _req$body$callbackUrl !== void 0 ? _req$body$callbackUrl : (_req$query2 = req.query) === null || _req$query2 === void 0 ? void 0 : _req$query2.callbackUrl,
csrfToken: (_req$body2 = req.body) === null || _req$body2 === void 0 ? void 0 : _req$body2.csrfToken,
cookies: req.cookies,
isPost: method === "POST"
});
const sessionStore = new _cookie.SessionStore(options.cookies.sessionToken, req, options.logger);
if (method === "GET") {
const render = (0, _pages.default)({
...options,
query: req.query,
cookies
});
const {
pages
} = options;
switch (action) {
case "providers":
return await routes.providers(options.providers);
case "session":
{
const session = await routes.session({
options,
sessionStore
});
if (session.cookies) cookies.push(...session.cookies);
return {
...session,
cookies
};
}
case "csrf":
return {
headers: [{
key: "Content-Type",
value: "application/json"
}],
body: {
csrfToken: options.csrfToken
},
cookies
};
case "signin":
if (pages.signIn) {
let signinUrl = `${pages.signIn}${pages.signIn.includes("?") ? "&" : "?"}callbackUrl=${encodeURIComponent(options.callbackUrl)}`;
if (error) signinUrl = `${signinUrl}&error=${encodeURIComponent(error)}`;
return {
redirect: signinUrl,
cookies
};
}
return render.signin();
case "signout":
if (pages.signOut) return {
redirect: pages.signOut,
cookies
};
return render.signout();
case "callback":
if (options.provider) {
const callback = await routes.callback({
body: req.body,
query: req.query,
headers: req.headers,
cookies: req.cookies,
method,
options,
sessionStore
});
if (callback.cookies) cookies.push(...callback.cookies);
return {
...callback,
cookies
};
}
break;
case "verify-request":
if (pages.verifyRequest) {
return {
redirect: pages.verifyRequest,
cookies
};
}
return render.verifyRequest();
case "error":
if (["Signin", "OAuthSignin", "OAuthCallback", "OAuthCreateAccount", "EmailCreateAccount", "Callback", "OAuthAccountNotLinked", "EmailSignin", "CredentialsSignin", "SessionRequired"].includes(error)) {
return {
redirect: `${options.url}/signin?error=${error}`,
cookies
};
}
if (pages.error) {
return {
redirect: `${pages.error}${pages.error.includes("?") ? "&" : "?"}error=${error}`,
cookies
};
}
return render.error({
error: error
});
default:
}
} else if (method === "POST") {
switch (action) {
case "signin":
if (options.csrfTokenVerified && options.provider) {
const signin = await routes.signin({
query: req.query,
body: req.body,
options
});
if (signin.cookies) cookies.push(...signin.cookies);
return {
...signin,
cookies
};
}
return {
redirect: `${options.url}/signin?csrf=true`,
cookies
};
case "signout":
if (options.csrfTokenVerified) {
const signout = await routes.signout({
options,
sessionStore
});
if (signout.cookies) cookies.push(...signout.cookies);
return {
...signout,
cookies
};
}
return {
redirect: `${options.url}/signout?csrf=true`,
cookies
};
case "callback":
if (options.provider) {
if (options.provider.type === "credentials" && !options.csrfTokenVerified) {
return {
redirect: `${options.url}/signin?csrf=true`,
cookies
};
}
const callback = await routes.callback({
body: req.body,
query: req.query,
headers: req.headers,
cookies: req.cookies,
method,
options,
sessionStore
});
if (callback.cookies) cookies.push(...callback.cookies);
return {
...callback,
cookies
};
}
break;
case "_log":
{
if (authOptions.logger) {
try {
var _req$body3;
const {
code,
level,
...metadata
} = (_req$body3 = req.body) !== null && _req$body3 !== void 0 ? _req$body3 : {};
_logger.default[level](code, metadata);
} catch (error) {
_logger.default.error("LOGGER_ERROR", error);
}
}
return {};
}
case "session":
{
if (options.csrfTokenVerified) {
var _req$body4;
const session = await routes.session({
options,
sessionStore,
newSession: (_req$body4 = req.body) === null || _req$body4 === void 0 ? void 0 : _req$body4.data,
isUpdate: true
});
if (session.cookies) cookies.push(...session.cookies);
return {
...session,
cookies
};
}
return {
status: 400,
body: {},
cookies
};
}
default:
}
}
return {
status: 400,
body: `Error: This action with HTTP ${method} is not supported by NextAuth.js`
};
}