next-auth
Version:
Authentication for Next.js
445 lines (403 loc) • 11.4 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = callback;
var _callback = _interopRequireDefault(require("../lib/oauth/callback"));
var _callbackHandler = _interopRequireDefault(require("../lib/callback-handler"));
var _utils = require("../lib/utils");
async function callback(params) {
const {
options,
query,
body,
method,
headers,
sessionStore
} = params;
const {
provider,
adapter,
url,
callbackUrl,
pages,
jwt,
events,
callbacks,
session: {
strategy: sessionStrategy,
maxAge: sessionMaxAge
},
logger
} = options;
const cookies = [];
const useJwtSession = sessionStrategy === "jwt";
if (provider.type === "oauth") {
try {
const {
profile,
account,
OAuthProfile,
cookies: oauthCookies
} = await (0, _callback.default)({
query,
body,
method,
options,
cookies: params.cookies
});
if (oauthCookies) cookies.push(...oauthCookies);
try {
var _events$signIn;
logger.debug("OAUTH_CALLBACK_RESPONSE", {
profile,
account,
OAuthProfile
});
if (!profile) {
return {
redirect: `${url}/signin`,
cookies
};
}
let userOrProfile = profile;
if (adapter) {
const {
getUserByAccount
} = adapter;
const userByAccount = await getUserByAccount({
providerAccountId: account.providerAccountId,
provider: provider.id
});
if (userByAccount) userOrProfile = userByAccount;
}
try {
const isAllowed = await callbacks.signIn({
user: userOrProfile,
account,
profile: OAuthProfile
});
if (!isAllowed) {
return {
redirect: `${url}/error?error=AccessDenied`,
cookies
};
} else if (typeof isAllowed === "string") {
return {
redirect: isAllowed,
cookies
};
}
} catch (error) {
return {
redirect: `${url}/error?error=${encodeURIComponent(error.message)}`,
cookies
};
}
const {
user,
session,
isNewUser
} = await (0, _callbackHandler.default)({
sessionToken: sessionStore.value,
profile,
account,
options
});
if (useJwtSession) {
var _user$id;
const defaultToken = {
name: user.name,
email: user.email,
picture: user.image,
sub: (_user$id = user.id) === null || _user$id === void 0 ? void 0 : _user$id.toString()
};
const token = await callbacks.jwt({
token: defaultToken,
user,
account,
profile: OAuthProfile,
isNewUser
});
const newToken = await jwt.encode({ ...jwt,
token
});
const cookieExpires = new Date();
cookieExpires.setTime(cookieExpires.getTime() + sessionMaxAge * 1000);
const sessionCookies = sessionStore.chunk(newToken, {
expires: cookieExpires
});
cookies.push(...sessionCookies);
} else {
cookies.push({
name: options.cookies.sessionToken.name,
value: session.sessionToken,
options: { ...options.cookies.sessionToken.options,
expires: session.expires
}
});
}
await ((_events$signIn = events.signIn) === null || _events$signIn === void 0 ? void 0 : _events$signIn.call(events, {
user,
account,
profile,
isNewUser
}));
if (isNewUser && pages.newUser) {
return {
redirect: `${pages.newUser}${pages.newUser.includes("?") ? "&" : "?"}callbackUrl=${encodeURIComponent(callbackUrl)}`,
cookies
};
}
return {
redirect: callbackUrl,
cookies
};
} catch (error) {
if (error.name === "AccountNotLinkedError") {
return {
redirect: `${url}/error?error=OAuthAccountNotLinked`,
cookies
};
} else if (error.name === "CreateUserError") {
return {
redirect: `${url}/error?error=OAuthCreateAccount`,
cookies
};
}
logger.error("OAUTH_CALLBACK_HANDLER_ERROR", error);
return {
redirect: `${url}/error?error=Callback`,
cookies
};
}
} catch (error) {
if (error.name === "OAuthCallbackError") {
logger.error("CALLBACK_OAUTH_ERROR", error);
return {
redirect: `${url}/error?error=OAuthCallback`,
cookies
};
}
logger.error("OAUTH_CALLBACK_ERROR", error);
return {
redirect: `${url}/error?error=Callback`,
cookies
};
}
} else if (provider.type === "email") {
try {
var _ref, _events$signIn2;
const {
useVerificationToken,
getUserByEmail
} = adapter;
const token = query === null || query === void 0 ? void 0 : query.token;
const identifier = query === null || query === void 0 ? void 0 : query.email;
const invite = await (useVerificationToken === null || useVerificationToken === void 0 ? void 0 : useVerificationToken({
identifier,
token: (0, _utils.hashToken)(token, options)
}));
const invalidInvite = !invite || invite.expires.valueOf() < Date.now();
if (invalidInvite) {
return {
redirect: `${url}/error?error=Verification`,
cookies
};
}
const profile = (_ref = identifier ? await getUserByEmail(identifier) : null) !== null && _ref !== void 0 ? _ref : {
email: identifier
};
const account = {
providerAccountId: profile.email,
type: "email",
provider: provider.id
};
try {
const signInCallbackResponse = await callbacks.signIn({
user: profile,
account,
email: {
email: identifier
}
});
if (!signInCallbackResponse) {
return {
redirect: `${url}/error?error=AccessDenied`,
cookies
};
} else if (typeof signInCallbackResponse === "string") {
return {
redirect: signInCallbackResponse,
cookies
};
}
} catch (error) {
return {
redirect: `${url}/error?error=${encodeURIComponent(error.message)}`,
cookies
};
}
const {
user,
session,
isNewUser
} = await (0, _callbackHandler.default)({
sessionToken: sessionStore.value,
profile,
account,
options
});
if (useJwtSession) {
var _user$id2;
const defaultToken = {
name: user.name,
email: user.email,
picture: user.image,
sub: (_user$id2 = user.id) === null || _user$id2 === void 0 ? void 0 : _user$id2.toString()
};
const token = await callbacks.jwt({
token: defaultToken,
user,
account,
isNewUser
});
const newToken = await jwt.encode({ ...jwt,
token
});
const cookieExpires = new Date();
cookieExpires.setTime(cookieExpires.getTime() + sessionMaxAge * 1000);
const sessionCookies = sessionStore.chunk(newToken, {
expires: cookieExpires
});
cookies.push(...sessionCookies);
} else {
cookies.push({
name: options.cookies.sessionToken.name,
value: session.sessionToken,
options: { ...options.cookies.sessionToken.options,
expires: session.expires
}
});
}
await ((_events$signIn2 = events.signIn) === null || _events$signIn2 === void 0 ? void 0 : _events$signIn2.call(events, {
user,
account,
isNewUser
}));
if (isNewUser && pages.newUser) {
return {
redirect: `${pages.newUser}${pages.newUser.includes("?") ? "&" : "?"}callbackUrl=${encodeURIComponent(callbackUrl)}`,
cookies
};
}
return {
redirect: callbackUrl,
cookies
};
} catch (error) {
if (error.name === "CreateUserError") {
return {
redirect: `${url}/error?error=EmailCreateAccount`,
cookies
};
}
logger.error("CALLBACK_EMAIL_ERROR", error);
return {
redirect: `${url}/error?error=Callback`,
cookies
};
}
} else if (provider.type === "credentials" && method === "POST") {
var _user$id3, _events$signIn3;
const credentials = body;
let user;
try {
user = await provider.authorize(credentials, {
query,
body,
headers,
method
});
if (!user) {
return {
status: 401,
redirect: `${url}/error?${new URLSearchParams({
error: "CredentialsSignin",
provider: provider.id
})}`,
cookies
};
}
} catch (error) {
return {
redirect: `${url}/error?error=${encodeURIComponent(error.message)}`,
cookies
};
}
const account = {
providerAccountId: user.id,
type: "credentials",
provider: provider.id
};
try {
const isAllowed = await callbacks.signIn({
user,
account,
credentials
});
if (!isAllowed) {
return {
status: 403,
redirect: `${url}/error?error=AccessDenied`,
cookies
};
} else if (typeof isAllowed === "string") {
return {
redirect: isAllowed,
cookies
};
}
} catch (error) {
return {
redirect: `${url}/error?error=${encodeURIComponent(error.message)}`,
cookies
};
}
const defaultToken = {
name: user.name,
email: user.email,
picture: user.image,
sub: (_user$id3 = user.id) === null || _user$id3 === void 0 ? void 0 : _user$id3.toString()
};
const token = await callbacks.jwt({
token: defaultToken,
user,
account,
isNewUser: false
});
const newToken = await jwt.encode({ ...jwt,
token
});
const cookieExpires = new Date();
cookieExpires.setTime(cookieExpires.getTime() + sessionMaxAge * 1000);
const sessionCookies = sessionStore.chunk(newToken, {
expires: cookieExpires
});
cookies.push(...sessionCookies);
await ((_events$signIn3 = events.signIn) === null || _events$signIn3 === void 0 ? void 0 : _events$signIn3.call(events, {
user,
account
}));
return {
redirect: callbackUrl,
cookies
};
}
return {
status: 500,
body: `Error: Callback for provider type ${provider.type} not supported`,
cookies
};
}
;