UNPKG

next-auth

Version:

Authentication for Next.js

545 lines (544 loc) 22.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); var _exportNames = { SessionContext: true, useSession: true, getSession: true, getCsrfToken: true, getProviders: true, signIn: true, signOut: true, SessionProvider: true }; exports.SessionContext = void 0; exports.SessionProvider = SessionProvider; exports.getCsrfToken = getCsrfToken; exports.getProviders = getProviders; exports.getSession = getSession; exports.signIn = signIn; exports.signOut = signOut; exports.useSession = useSession; var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var React = _interopRequireWildcard(require("react")); var _logger2 = _interopRequireWildcard(require("../utils/logger")); var _parseUrl = _interopRequireDefault(require("../utils/parse-url")); var _utils = require("../client/_utils"); var _jsxRuntime = require("react/jsx-runtime"); var _types = require("./types"); Object.keys(_types).forEach(function (key) { if (key === "default" || key === "__esModule") return; if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return; if (key in exports && exports[key] === _types[key]) return; Object.defineProperty(exports, key, { enumerable: true, get: function get() { return _types[key]; } }); }); var _process$env$NEXTAUTH, _ref, _process$env$NEXTAUTH2, _process$env$NEXTAUTH3, _React$createContext; function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(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; } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } var __NEXTAUTH = { baseUrl: (0, _parseUrl.default)((_process$env$NEXTAUTH = process.env.NEXTAUTH_URL) !== null && _process$env$NEXTAUTH !== void 0 ? _process$env$NEXTAUTH : process.env.VERCEL_URL).origin, basePath: (0, _parseUrl.default)(process.env.NEXTAUTH_URL).path, baseUrlServer: (0, _parseUrl.default)((_ref = (_process$env$NEXTAUTH2 = process.env.NEXTAUTH_URL_INTERNAL) !== null && _process$env$NEXTAUTH2 !== void 0 ? _process$env$NEXTAUTH2 : process.env.NEXTAUTH_URL) !== null && _ref !== void 0 ? _ref : process.env.VERCEL_URL).origin, basePathServer: (0, _parseUrl.default)((_process$env$NEXTAUTH3 = process.env.NEXTAUTH_URL_INTERNAL) !== null && _process$env$NEXTAUTH3 !== void 0 ? _process$env$NEXTAUTH3 : process.env.NEXTAUTH_URL).path, _lastSync: 0, _session: undefined, _getSession: function _getSession() {} }; var broadcast = (0, _utils.BroadcastChannel)(); var logger = (0, _logger2.proxyLogger)(_logger2.default, __NEXTAUTH.basePath); function useOnline() { var _React$useState = React.useState(typeof navigator !== "undefined" ? navigator.onLine : false), _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2), isOnline = _React$useState2[0], setIsOnline = _React$useState2[1]; var setOnline = function setOnline() { return setIsOnline(true); }; var setOffline = function setOffline() { return setIsOnline(false); }; React.useEffect(function () { window.addEventListener("online", setOnline); window.addEventListener("offline", setOffline); return function () { window.removeEventListener("online", setOnline); window.removeEventListener("offline", setOffline); }; }, []); return isOnline; } var SessionContext = exports.SessionContext = (_React$createContext = React.createContext) === null || _React$createContext === void 0 ? void 0 : _React$createContext.call(React, undefined); function useSession(options) { if (!SessionContext) { throw new Error("React Context is unavailable in Server Components"); } var value = React.useContext(SessionContext); if (!value && process.env.NODE_ENV !== "production") { throw new Error("[next-auth]: `useSession` must be wrapped in a <SessionProvider />"); } var _ref2 = options !== null && options !== void 0 ? options : {}, required = _ref2.required, onUnauthenticated = _ref2.onUnauthenticated; var requiredAndNotLoading = required && value.status === "unauthenticated"; React.useEffect(function () { if (requiredAndNotLoading) { var url = "/api/auth/signin?".concat(new URLSearchParams({ error: "SessionRequired", callbackUrl: window.location.href })); if (onUnauthenticated) onUnauthenticated();else window.location.href = url; } }, [requiredAndNotLoading, onUnauthenticated]); if (requiredAndNotLoading) { return { data: value.data, update: value.update, status: "loading" }; } return value; } function getSession(_x) { return _getSession2.apply(this, arguments); } function _getSession2() { _getSession2 = (0, _asyncToGenerator2.default)(_regenerator.default.mark(function _callee3(params) { var _params$broadcast; var session; return _regenerator.default.wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: _context3.next = 2; return (0, _utils.fetchData)("session", __NEXTAUTH, logger, params); case 2: session = _context3.sent; if ((_params$broadcast = params === null || params === void 0 ? void 0 : params.broadcast) !== null && _params$broadcast !== void 0 ? _params$broadcast : true) { broadcast.post({ event: "session", data: { trigger: "getSession" } }); } return _context3.abrupt("return", session); case 5: case "end": return _context3.stop(); } }, _callee3); })); return _getSession2.apply(this, arguments); } function getCsrfToken(_x2) { return _getCsrfToken.apply(this, arguments); } function _getCsrfToken() { _getCsrfToken = (0, _asyncToGenerator2.default)(_regenerator.default.mark(function _callee4(params) { var response; return _regenerator.default.wrap(function _callee4$(_context4) { while (1) switch (_context4.prev = _context4.next) { case 0: _context4.next = 2; return (0, _utils.fetchData)("csrf", __NEXTAUTH, logger, params); case 2: response = _context4.sent; return _context4.abrupt("return", response === null || response === void 0 ? void 0 : response.csrfToken); case 4: case "end": return _context4.stop(); } }, _callee4); })); return _getCsrfToken.apply(this, arguments); } function getProviders() { return _getProviders.apply(this, arguments); } function _getProviders() { _getProviders = (0, _asyncToGenerator2.default)(_regenerator.default.mark(function _callee5() { return _regenerator.default.wrap(function _callee5$(_context5) { while (1) switch (_context5.prev = _context5.next) { case 0: _context5.next = 2; return (0, _utils.fetchData)("providers", __NEXTAUTH, logger); case 2: return _context5.abrupt("return", _context5.sent); case 3: case "end": return _context5.stop(); } }, _callee5); })); return _getProviders.apply(this, arguments); } function signIn(_x3, _x4, _x5) { return _signIn.apply(this, arguments); } function _signIn() { _signIn = (0, _asyncToGenerator2.default)(_regenerator.default.mark(function _callee6(provider, options, authorizationParams) { var _ref5, _ref5$callbackUrl, callbackUrl, _ref5$redirect, redirect, baseUrl, providers, isCredentials, isEmail, isSupportingReturn, signInUrl, _signInUrl, res, data, _data$url, url, error; return _regenerator.default.wrap(function _callee6$(_context6) { while (1) switch (_context6.prev = _context6.next) { case 0: _ref5 = options !== null && options !== void 0 ? options : {}, _ref5$callbackUrl = _ref5.callbackUrl, callbackUrl = _ref5$callbackUrl === void 0 ? window.location.href : _ref5$callbackUrl, _ref5$redirect = _ref5.redirect, redirect = _ref5$redirect === void 0 ? true : _ref5$redirect; baseUrl = (0, _utils.apiBaseUrl)(__NEXTAUTH); _context6.next = 4; return getProviders(); case 4: providers = _context6.sent; if (providers) { _context6.next = 8; break; } window.location.href = "".concat(baseUrl, "/error"); return _context6.abrupt("return"); case 8: if (!(!provider || !(provider in providers))) { _context6.next = 11; break; } window.location.href = "".concat(baseUrl, "/signin?").concat(new URLSearchParams({ callbackUrl: callbackUrl })); return _context6.abrupt("return"); case 11: isCredentials = providers[provider].type === "credentials"; isEmail = providers[provider].type === "email"; isSupportingReturn = isCredentials || isEmail; signInUrl = "".concat(baseUrl, "/").concat(isCredentials ? "callback" : "signin", "/").concat(provider); _signInUrl = "".concat(signInUrl).concat(authorizationParams ? "?".concat(new URLSearchParams(authorizationParams)) : ""); _context6.t0 = fetch; _context6.t1 = _signInUrl; _context6.t2 = { "Content-Type": "application/x-www-form-urlencoded" }; _context6.t3 = URLSearchParams; _context6.t4 = _objectSpread; _context6.t5 = _objectSpread({}, options); _context6.t6 = {}; _context6.next = 25; return getCsrfToken(); case 25: _context6.t7 = _context6.sent; _context6.t8 = callbackUrl; _context6.t9 = { csrfToken: _context6.t7, callbackUrl: _context6.t8, json: true }; _context6.t10 = (0, _context6.t4)(_context6.t5, _context6.t6, _context6.t9); _context6.t11 = new _context6.t3(_context6.t10); _context6.t12 = { method: "post", headers: _context6.t2, body: _context6.t11 }; _context6.next = 33; return (0, _context6.t0)(_context6.t1, _context6.t12); case 33: res = _context6.sent; _context6.next = 36; return res.json(); case 36: data = _context6.sent; if (!(redirect || !isSupportingReturn)) { _context6.next = 42; break; } url = (_data$url = data.url) !== null && _data$url !== void 0 ? _data$url : callbackUrl; window.location.href = url; if (url.includes("#")) window.location.reload(); return _context6.abrupt("return"); case 42: error = new URL(data.url).searchParams.get("error"); if (!res.ok) { _context6.next = 46; break; } _context6.next = 46; return __NEXTAUTH._getSession({ event: "storage" }); case 46: return _context6.abrupt("return", { error: error, status: res.status, ok: res.ok, url: error ? null : data.url }); case 47: case "end": return _context6.stop(); } }, _callee6); })); return _signIn.apply(this, arguments); } function signOut(_x6) { return _signOut.apply(this, arguments); } function _signOut() { _signOut = (0, _asyncToGenerator2.default)(_regenerator.default.mark(function _callee7(options) { var _options$redirect; var _ref6, _ref6$callbackUrl, callbackUrl, baseUrl, fetchOptions, res, data, _data$url2, url; return _regenerator.default.wrap(function _callee7$(_context7) { while (1) switch (_context7.prev = _context7.next) { case 0: _ref6 = options !== null && options !== void 0 ? options : {}, _ref6$callbackUrl = _ref6.callbackUrl, callbackUrl = _ref6$callbackUrl === void 0 ? window.location.href : _ref6$callbackUrl; baseUrl = (0, _utils.apiBaseUrl)(__NEXTAUTH); _context7.t0 = { "Content-Type": "application/x-www-form-urlencoded" }; _context7.t1 = URLSearchParams; _context7.next = 6; return getCsrfToken(); case 6: _context7.t2 = _context7.sent; _context7.t3 = callbackUrl; _context7.t4 = { csrfToken: _context7.t2, callbackUrl: _context7.t3, json: true }; _context7.t5 = new _context7.t1(_context7.t4); fetchOptions = { method: "post", headers: _context7.t0, body: _context7.t5 }; _context7.next = 13; return fetch("".concat(baseUrl, "/signout"), fetchOptions); case 13: res = _context7.sent; _context7.next = 16; return res.json(); case 16: data = _context7.sent; broadcast.post({ event: "session", data: { trigger: "signout" } }); if (!((_options$redirect = options === null || options === void 0 ? void 0 : options.redirect) !== null && _options$redirect !== void 0 ? _options$redirect : true)) { _context7.next = 23; break; } url = (_data$url2 = data.url) !== null && _data$url2 !== void 0 ? _data$url2 : callbackUrl; window.location.href = url; if (url.includes("#")) window.location.reload(); return _context7.abrupt("return"); case 23: _context7.next = 25; return __NEXTAUTH._getSession({ event: "storage" }); case 25: return _context7.abrupt("return", data); case 26: case "end": return _context7.stop(); } }, _callee7); })); return _signOut.apply(this, arguments); } function SessionProvider(props) { if (!SessionContext) { throw new Error("React Context is unavailable in Server Components"); } var children = props.children, basePath = props.basePath, refetchInterval = props.refetchInterval, refetchWhenOffline = props.refetchWhenOffline; if (basePath) __NEXTAUTH.basePath = basePath; var hasInitialSession = props.session !== undefined; __NEXTAUTH._lastSync = hasInitialSession ? (0, _utils.now)() : 0; var _React$useState3 = React.useState(function () { if (hasInitialSession) __NEXTAUTH._session = props.session; return props.session; }), _React$useState4 = (0, _slicedToArray2.default)(_React$useState3, 2), session = _React$useState4[0], setSession = _React$useState4[1]; var _React$useState5 = React.useState(!hasInitialSession), _React$useState6 = (0, _slicedToArray2.default)(_React$useState5, 2), loading = _React$useState6[0], setLoading = _React$useState6[1]; React.useEffect(function () { __NEXTAUTH._getSession = (0, _asyncToGenerator2.default)(_regenerator.default.mark(function _callee() { var _ref4, event, storageEvent, _args = arguments; return _regenerator.default.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: _ref4 = _args.length > 0 && _args[0] !== undefined ? _args[0] : {}, event = _ref4.event; _context.prev = 1; storageEvent = event === "storage"; if (!(storageEvent || __NEXTAUTH._session === undefined)) { _context.next = 10; break; } __NEXTAUTH._lastSync = (0, _utils.now)(); _context.next = 7; return getSession({ broadcast: !storageEvent }); case 7: __NEXTAUTH._session = _context.sent; setSession(__NEXTAUTH._session); return _context.abrupt("return"); case 10: if (!(!event || __NEXTAUTH._session === null || (0, _utils.now)() < __NEXTAUTH._lastSync)) { _context.next = 12; break; } return _context.abrupt("return"); case 12: __NEXTAUTH._lastSync = (0, _utils.now)(); _context.next = 15; return getSession(); case 15: __NEXTAUTH._session = _context.sent; setSession(__NEXTAUTH._session); _context.next = 22; break; case 19: _context.prev = 19; _context.t0 = _context["catch"](1); logger.error("CLIENT_SESSION_ERROR", _context.t0); case 22: _context.prev = 22; setLoading(false); return _context.finish(22); case 25: case "end": return _context.stop(); } }, _callee, null, [[1, 19, 22, 25]]); })); __NEXTAUTH._getSession(); return function () { __NEXTAUTH._lastSync = 0; __NEXTAUTH._session = undefined; __NEXTAUTH._getSession = function () {}; }; }, []); React.useEffect(function () { var unsubscribe = broadcast.receive(function () { return __NEXTAUTH._getSession({ event: "storage" }); }); return function () { return unsubscribe(); }; }, []); React.useEffect(function () { var _props$refetchOnWindo = props.refetchOnWindowFocus, refetchOnWindowFocus = _props$refetchOnWindo === void 0 ? true : _props$refetchOnWindo; var visibilityHandler = function visibilityHandler() { if (refetchOnWindowFocus && document.visibilityState === "visible") __NEXTAUTH._getSession({ event: "visibilitychange" }); }; document.addEventListener("visibilitychange", visibilityHandler, false); return function () { return document.removeEventListener("visibilitychange", visibilityHandler, false); }; }, [props.refetchOnWindowFocus]); var isOnline = useOnline(); var shouldRefetch = refetchWhenOffline !== false || isOnline; React.useEffect(function () { if (refetchInterval && shouldRefetch) { var refetchIntervalTimer = setInterval(function () { if (__NEXTAUTH._session) { __NEXTAUTH._getSession({ event: "poll" }); } }, refetchInterval * 1000); return function () { return clearInterval(refetchIntervalTimer); }; } }, [refetchInterval, shouldRefetch]); var value = React.useMemo(function () { return { data: session, status: loading ? "loading" : session ? "authenticated" : "unauthenticated", update: function update(data) { return (0, _asyncToGenerator2.default)(_regenerator.default.mark(function _callee2() { var newSession; return _regenerator.default.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: if (!(loading || !session)) { _context2.next = 2; break; } return _context2.abrupt("return"); case 2: setLoading(true); _context2.t0 = _utils.fetchData; _context2.t1 = __NEXTAUTH; _context2.t2 = logger; _context2.next = 8; return getCsrfToken(); case 8: _context2.t3 = _context2.sent; _context2.t4 = data; _context2.t5 = { csrfToken: _context2.t3, data: _context2.t4 }; _context2.t6 = { body: _context2.t5 }; _context2.t7 = { req: _context2.t6 }; _context2.next = 15; return (0, _context2.t0)("session", _context2.t1, _context2.t2, _context2.t7); case 15: newSession = _context2.sent; setLoading(false); if (newSession) { setSession(newSession); broadcast.post({ event: "session", data: { trigger: "getSession" } }); } return _context2.abrupt("return", newSession); case 19: case "end": return _context2.stop(); } }, _callee2); }))(); } }; }, [session, loading]); return (0, _jsxRuntime.jsx)(SessionContext.Provider, { value: value, children: children }); }