better-auth
Version:
The most comprehensive authentication framework for TypeScript.
54 lines (53 loc) • 1.97 kB
JavaScript
import { generateRandomString } from "../crypto/random.mjs";
import { redirectOnError } from "./errors.mjs";
import { setOAuthState } from "../api/state/oauth.mjs";
import { StateError, generateGenericState, parseGenericState } from "../state.mjs";
import { APIError, BASE_ERROR_CODES } from "@better-auth/core/error";
//#region src/oauth2/state.ts
async function generateState(c, link, additionalData) {
const callbackURL = c.body?.callbackURL || c.context.options.baseURL;
if (!callbackURL) throw APIError.from("BAD_REQUEST", BASE_ERROR_CODES.CALLBACK_URL_REQUIRED);
const codeVerifier = generateRandomString(128);
const stateData = {
...additionalData ? additionalData : {},
callbackURL,
codeVerifier,
errorURL: c.body?.errorCallbackURL,
newUserURL: c.body?.newUserCallbackURL,
link,
expiresAt: Date.now() + 600 * 1e3,
requestSignUp: c.body?.requestSignUp
};
await setOAuthState(stateData);
try {
return generateGenericState(c, stateData);
} catch (error) {
c.context.logger.error("Failed to create verification", error);
throw new APIError("INTERNAL_SERVER_ERROR", {
message: "Unable to create verification",
cause: error
});
}
}
async function parseState(c) {
const state = c.query.state || c.body?.state;
const errorURL = c.context.options.onAPIError?.errorURL || `${c.context.baseURL}/error`;
let parsedData;
try {
parsedData = await parseGenericState(c, state);
} catch (error) {
c.context.logger.error("Failed to parse state", error);
let code = "internal_server_error";
let redirectErrorURL = errorURL;
if (error instanceof StateError) {
code = error.code === "state_security_mismatch" ? "state_mismatch" : error.code;
redirectErrorURL = error.errorURL ?? errorURL;
}
redirectOnError(c, redirectErrorURL, code);
}
if (!parsedData.errorURL) parsedData.errorURL = errorURL;
if (parsedData) await setOAuthState(parsedData);
return parsedData;
}
//#endregion
export { generateState, parseState };