@ory/nextjs
Version:
This package contains the Next.js SDK for Ory. It provides a set of React components, server-side components, and hooks to interact with the Ory ecosystem. Supports both app and page routers.
224 lines (218 loc) • 7.43 kB
JavaScript
import { FlowType, handleFlowError, FrontendApi, Configuration } from '@ory/client-fetch';
import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import { useSearchParams } from 'next/navigation';
import 'cookie';
import 'set-cookie-parser';
import 'psl';
// src/utils/sdk.ts
function getEnv(name) {
return process.env[`NEXT_PUBLIC_${name}`] || process.env[name];
}
function orySdkUrl() {
const baseUrl = getEnv("ORY_SDK_URL");
if (!baseUrl) {
throw new Error(
"You need to set environment variable `NEXT_PUBLIC_ORY_SDK_URL` to your Ory Network SDK URL."
);
}
return baseUrl.replace(/\/$/, "");
}
function isProduction() {
const env = getEnv("VERCEL_ENV") || getEnv("NODE_ENV") || "";
return ["production", "prod"].indexOf(env) > -1;
}
function guessPotentiallyProxiedOrySdkUrl(options) {
if (getEnv("VERCEL_ENV")) {
if (!isProduction() && getEnv("VERCEL_URL")) {
return `https://${getEnv("VERCEL_URL")}`.replace(/\/$/, "");
}
const productionUrl = getEnv("VERCEL_PROJECT_PRODUCTION_URL") || "";
if (isProduction() && productionUrl.indexOf("vercel.app") > -1) {
return `https://${productionUrl}`.replace(/\/$/, "");
}
if (process.env["__NEXT_PRIVATE_ORIGIN"]) {
return process.env["__NEXT_PRIVATE_ORIGIN"].replace(/\/$/, "");
}
}
if (isProduction()) {
return orySdkUrl();
}
if (typeof window !== "undefined") {
return window.location.origin;
}
if (options == null ? void 0 : options.knownProxiedUrl) {
return options.knownProxiedUrl;
}
const final = orySdkUrl();
console.warn(
`Unable to determine a suitable SDK URL for setting up the Next.js integration of Ory Elements. Will proceed using default Ory SDK URL "${final}". This is likely not what you want for local development and your authentication and login may not work.`
);
return final;
}
// src/pages/client.ts
var clientSideFrontendClient = () => new FrontendApi(
new Configuration({
headers: {
Accept: "application/json"
},
credentials: "include",
basePath: guessPotentiallyProxiedOrySdkUrl({
knownProxiedUrl: window.location.origin
})
})
);
function onValidationError(value) {
return value;
}
var toBrowserEndpointRedirect = (params, flowType) => guessPotentiallyProxiedOrySdkUrl({
knownProxiedUrl: window.location.origin
}) + "/self-service/" + flowType.toString() + "/browser?" + new URLSearchParams(params).toString();
var handleRestartFlow = (searchParams, flowType) => () => {
window.location.assign(toBrowserEndpointRedirect(searchParams, flowType));
};
function useOnRedirect() {
const router = useRouter();
return (url, external) => {
if (external) {
window.location.assign(url);
} else {
void router.push(url);
}
};
}
// src/utils/rewrite.ts
function rewriteJsonResponse(obj, proxyUrl) {
return Object.fromEntries(
Object.entries(obj).filter(([_, value]) => value !== void 0).map(([key, value]) => {
if (Array.isArray(value)) {
return [
key,
value.map((item) => {
if (typeof item === "object" && item !== null) {
return rewriteJsonResponse(item);
}
return item;
}).filter((item) => item !== void 0)
];
} else if (typeof value === "object" && value !== null) {
return [key, rewriteJsonResponse(value)];
} else ;
return [key, value];
})
);
}
// src/utils/utils.ts
function toValue(res) {
return res.value().then((v) => rewriteJsonResponse(v));
}
// src/pages/flow.ts
function createUseFlowFactory(flowType, createFlow, getFlow) {
return () => {
const [flow, setFlow] = useState();
const router = useRouter();
const searchParams = useSearchParams();
const onRestartFlow = handleRestartFlow(searchParams, flowType);
const onRedirect = useOnRedirect();
const errorHandler = handleFlowError({
onValidationError,
onRestartFlow,
onRedirect
});
const handleSetFlow = async (flow2) => {
setFlow(flow2);
await router.replace({
query: { flow: flow2.id }
});
return;
};
useEffect(() => {
const id = searchParams.get("flow");
if (!router.isReady || flow !== void 0) {
return;
}
if (!id) {
createFlow(searchParams).then(toValue).then(handleSetFlow).catch(errorHandler);
return;
}
getFlow(id).then(toValue).then(handleSetFlow).catch(errorHandler);
}, [searchParams, router, router.isReady, flow]);
return flow;
};
}
var useRegistrationFlow = createUseFlowFactory(
FlowType.Registration,
(params) => {
var _a, _b, _c, _d;
return clientSideFrontendClient().createBrowserRegistrationFlowRaw({
returnTo: (_a = params.get("return_to")) != null ? _a : void 0,
loginChallenge: (_b = params.get("registration_challenge")) != null ? _b : void 0,
afterVerificationReturnTo: (_c = params.get("after_verification_return_to")) != null ? _c : void 0,
organization: (_d = params.get("organization")) != null ? _d : void 0
});
},
(id) => clientSideFrontendClient().getRegistrationFlowRaw({ id })
);
var useVerificationFlow = createUseFlowFactory(
FlowType.Verification,
(params) => {
var _a;
return clientSideFrontendClient().createBrowserVerificationFlowRaw({
returnTo: (_a = params.get("return_to")) != null ? _a : void 0
});
},
(id) => clientSideFrontendClient().getVerificationFlowRaw({ id })
);
var useRecoveryFlow = createUseFlowFactory(
FlowType.Recovery,
(params) => {
var _a;
return clientSideFrontendClient().createBrowserRecoveryFlowRaw({
returnTo: (_a = params.get("return_to")) != null ? _a : void 0
});
},
(id) => clientSideFrontendClient().getRecoveryFlowRaw({ id })
);
var useLoginFlow = createUseFlowFactory(
FlowType.Login,
(params) => {
var _a, _b, _c, _d, _e, _f;
return clientSideFrontendClient().createBrowserLoginFlowRaw({
refresh: params.get("refresh") === "true",
aal: (_a = params.get("aal")) != null ? _a : void 0,
returnTo: (_b = params.get("return_to")) != null ? _b : void 0,
cookie: (_c = params.get("cookie")) != null ? _c : void 0,
loginChallenge: (_d = params.get("login_challenge")) != null ? _d : void 0,
organization: (_e = params.get("organization")) != null ? _e : void 0,
via: (_f = params.get("via")) != null ? _f : void 0
});
},
(id) => clientSideFrontendClient().getLoginFlowRaw({ id })
);
var useSettingsFlow = createUseFlowFactory(
FlowType.Settings,
(params) => {
var _a, _b;
return clientSideFrontendClient().createBrowserSettingsFlowRaw({
returnTo: (_a = params.get("return_to")) != null ? _a : void 0,
cookie: (_b = params.get("cookie")) != null ? _b : void 0
});
},
(id) => clientSideFrontendClient().getSettingsFlowRaw({ id })
);
function useLogoutFlow() {
const [flow, setFlow] = useState(void 0);
const createFlow = async () => {
const flow2 = await clientSideFrontendClient().createBrowserLogoutFlow({});
setFlow(flow2);
};
useEffect(() => {
if (!flow) {
void createFlow();
}
}, []);
return flow;
}
export { useLoginFlow, useLogoutFlow, useRecoveryFlow, useRegistrationFlow, useSettingsFlow, useVerificationFlow };
//# sourceMappingURL=index.mjs.map
//# sourceMappingURL=index.mjs.map