mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-04 21:04:37 +08:00
Rename Stack -> Hexclave in examples, app-internal symbols, and crypto docs
- examples: rename the user config module stack.ts/.tsx (and the convex/lovable
stack/ dirs) to hexclave and update all importers across .ts/.tsx/.jsx; the
public handler/[...stack] route segment is left unchanged.
- apps/{dashboard,backend,internal-tool}: rename app-local SDK-init symbols
(stackClientApp -> hexclaveClientApp, getStackServerApp -> getHexclaveServerApp)
and the dashboard StackCompanion component -> HexclaveCompanion. The public
StackClientApp/StackServerApp SDK classes are intentionally left unchanged.
- packages/stack-shared: add comments explaining why the crypto/JWT/vault
"stack-*" literals must NOT be renamed (key derivation / JWKS / KMS-alias
stability would break existing encrypted data and tokens).
Deliberately excluded: the STACK_* -> HEXCLAVE_* env-var rename (already works via
the dual-read layers; the docker post-build sentinel path is author-deferred), and
all public-contract names (SDK classes, env vars, HTTP headers, handler routes).
This commit is contained in:
parent
6fb99c4340
commit
8fc11e1c93
@ -1,7 +1,7 @@
|
||||
import { getClickhouseAdminClient } from "@/lib/clickhouse";
|
||||
import { arePlanLimitsEnforced, getBillingTeamId } from "@/lib/plan-entitlements";
|
||||
import { findRecentSessionReplay } from "@/lib/session-replays";
|
||||
import { getStackServerApp } from "@/stack";
|
||||
import { getHexclaveServerApp } from "@/stack";
|
||||
import { getPrismaClientForTenancy } from "@/prisma-client";
|
||||
import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler";
|
||||
import { KnownErrors } from "@hexclave/shared";
|
||||
@ -118,7 +118,7 @@ export const POST = createSmartRouteHandler({
|
||||
const refreshTokenId = auth.refreshTokenId;
|
||||
const tenancyId = auth.tenancy.id;
|
||||
|
||||
const app = getStackServerApp();
|
||||
const app = getHexclaveServerApp();
|
||||
|
||||
const billingTeamId = getBillingTeamId(auth.tenancy.project);
|
||||
if (billingTeamId != null && arePlanLimitsEnforced()) {
|
||||
|
||||
@ -2,7 +2,7 @@ import { getClickhouseExternalClient } from "@/lib/clickhouse";
|
||||
import { getSafeClickhouseErrorMessage } from "@/lib/clickhouse-errors";
|
||||
import { arePlanLimitsEnforced, getBillingTeamId } from "@/lib/plan-entitlements";
|
||||
import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler";
|
||||
import { getStackServerApp } from "@/stack";
|
||||
import { getHexclaveServerApp } from "@/stack";
|
||||
import { KnownErrors } from "@hexclave/shared";
|
||||
import { ITEM_IDS, PLAN_LIMITS } from "@hexclave/shared/dist/plans";
|
||||
import { adaptSchema, adminAuthTypeSchema, jsonSchema, yupBoolean, yupMixed, yupNumber, yupObject, yupRecord, yupString } from "@hexclave/shared/dist/schema-fields";
|
||||
@ -43,7 +43,7 @@ export const POST = createSmartRouteHandler({
|
||||
let effectiveTimeoutMs = body.timeout_ms;
|
||||
const billingTeamId = getBillingTeamId(auth.tenancy.project);
|
||||
if (billingTeamId != null && arePlanLimitsEnforced()) {
|
||||
const app = getStackServerApp();
|
||||
const app = getHexclaveServerApp();
|
||||
const timeoutItem = await app.getItem({ itemId: ITEM_IDS.analyticsTimeoutSeconds, teamId: billingTeamId });
|
||||
// clickHouse treats max_execution_time=0 as
|
||||
// "unlimited", so a customer with zero timeout entitlement (no active
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { isSecureEmailPort, lowLevelSendEmailDirectWithoutRetries } from "@/lib/emails-low-level";
|
||||
import { arePlanLimitsEnforced, getBillingTeamId } from "@/lib/plan-entitlements";
|
||||
import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler";
|
||||
import { getStackServerApp } from "@/stack";
|
||||
import { getHexclaveServerApp } from "@/stack";
|
||||
import { KnownErrors } from "@hexclave/shared";
|
||||
import { ITEM_IDS } from "@hexclave/shared/dist/plans";
|
||||
import * as schemaFields from "@hexclave/shared/dist/schema-fields";
|
||||
@ -51,7 +51,7 @@ export const POST = createSmartRouteHandler({
|
||||
const billingTeamId = getBillingTeamId(auth.tenancy.project);
|
||||
const emailItem = billingTeamId == null || !arePlanLimitsEnforced()
|
||||
? null
|
||||
: await getStackServerApp().getItem({ itemId: ITEM_IDS.emailsPerMonth, teamId: billingTeamId });
|
||||
: await getHexclaveServerApp().getItem({ itemId: ITEM_IDS.emailsPerMonth, teamId: billingTeamId });
|
||||
if (emailItem != null && billingTeamId != null) {
|
||||
const isDebited = await emailItem.tryDecreaseQuantity(1);
|
||||
if (!isDebited) {
|
||||
|
||||
@ -4,7 +4,7 @@ import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler";
|
||||
import { Prisma } from "@/generated/prisma/client";
|
||||
import { arePlanLimitsEnforced, getBillingTeamId } from "@/lib/plan-entitlements";
|
||||
import { findRecentSessionReplay } from "@/lib/session-replays";
|
||||
import { getStackServerApp } from "@/stack";
|
||||
import { getHexclaveServerApp } from "@/stack";
|
||||
import { KnownErrors } from "@hexclave/shared";
|
||||
import { ITEM_IDS } from "@hexclave/shared/dist/plans";
|
||||
import { adaptSchema, clientOrHigherAuthTypeSchema, yupArray, yupMixed, yupNumber, yupObject, yupString } from "@hexclave/shared/dist/schema-fields";
|
||||
@ -109,7 +109,7 @@ export const POST = createSmartRouteHandler({
|
||||
const prisma = await getPrismaClientForTenancy(auth.tenancy);
|
||||
const recentSession = await findRecentSessionReplay(prisma, { tenancyId, refreshTokenId });
|
||||
|
||||
const app = getStackServerApp();
|
||||
const app = getHexclaveServerApp();
|
||||
|
||||
const isNewSession = recentSession == null;
|
||||
const billingTeamId = getBillingTeamId(auth.tenancy.project);
|
||||
|
||||
@ -4,7 +4,7 @@ import { getEmailThemeForThemeId, renderEmailsForTenancyBatched } from "@/lib/em
|
||||
import { EmailOutboxRecipient, getEmailConfig, } from "@/lib/emails";
|
||||
import { generateUnsubscribeLink, getNotificationCategoryById, hasNotificationEnabled, listNotificationCategories } from "@/lib/notification-categories";
|
||||
import { arePlanLimitsEnforced, getBillingTeamId } from "@/lib/plan-entitlements";
|
||||
import { getStackServerApp } from "@/stack";
|
||||
import { getHexclaveServerApp } from "@/stack";
|
||||
import { ITEM_IDS } from "@hexclave/shared/dist/plans";
|
||||
import { getTenancy, Tenancy } from "@/lib/tenancies";
|
||||
import { getPrismaClientForTenancy, globalPrismaClient, PrismaClientTransaction } from "@/prisma-client";
|
||||
@ -695,7 +695,7 @@ async function processSingleEmail(context: TenancyProcessingContext, row: EmailO
|
||||
}
|
||||
|
||||
if (context.billingTeamId != null && row.sendRetries === 0 && arePlanLimitsEnforced()) {
|
||||
const app = getStackServerApp();
|
||||
const app = getHexclaveServerApp();
|
||||
const emailItem = await app.getItem({ itemId: ITEM_IDS.emailsPerMonth, teamId: context.billingTeamId });
|
||||
const isDebited = await emailItem.tryDecreaseQuantity(1);
|
||||
if (!isDebited) {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import withPostHog from "@/analytics";
|
||||
import { arePlanLimitsEnforced } from "@/lib/plan-entitlements";
|
||||
import { globalPrismaClient } from "@/prisma-client";
|
||||
import { getStackServerApp } from "@/stack";
|
||||
import { getHexclaveServerApp } from "@/stack";
|
||||
import { runAsynchronouslyAndWaitUntil } from "@/utils/background-tasks";
|
||||
import { ITEM_IDS } from "@hexclave/shared/dist/plans";
|
||||
import { urlSchema, yupBoolean, yupMixed, yupNumber, yupObject, yupString } from "@hexclave/shared/dist/schema-fields";
|
||||
@ -278,7 +278,7 @@ export async function logEvent<T extends EventType[]>(
|
||||
const billingTeamId = options.billingTeamId;
|
||||
|
||||
if (billingTeamId != null && arePlanLimitsEnforced()) {
|
||||
const app = getStackServerApp();
|
||||
const app = getHexclaveServerApp();
|
||||
const eventsItem = await app.getItem({ itemId: ITEM_IDS.analyticsEvents, teamId: billingTeamId });
|
||||
const isDebited = await eventsItem.tryDecreaseQuantity(1);
|
||||
if (!isDebited) {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { StackServerApp } from '@hexclave/next';
|
||||
import { getEnvVariable } from '@hexclave/shared/dist/utils/env';
|
||||
|
||||
export function getStackServerApp() {
|
||||
export function getHexclaveServerApp() {
|
||||
// Fail fast if the backend self-URL env var is missing — without it the SDK
|
||||
// would silently inherit `defaultBaseUrl` (https://api.stack-auth.com), which
|
||||
// is almost never what we want for backend self-calls.
|
||||
|
||||
@ -5,7 +5,7 @@ async function getServerApp() {
|
||||
if (isRemoteDevelopmentEnvironmentEnabled()) {
|
||||
throw new Error("Team invitation management is not available in the remote development environment dashboard.");
|
||||
}
|
||||
return (await import("@/stack/server")).getStackServerApp();
|
||||
return (await import("@/stack/server")).getHexclaveServerApp();
|
||||
}
|
||||
|
||||
export async function revokeInvitation(teamId: string, invitationId: string) {
|
||||
|
||||
@ -4,7 +4,7 @@ import { CmdKSearch, CmdKTrigger } from "@/components/cmdk-search";
|
||||
import { Link } from "@/components/link";
|
||||
import { Logo } from "@/components/logo";
|
||||
import { ProjectSwitcher } from "@/components/project-switcher";
|
||||
import { StackCompanion } from "@/components/stack-companion";
|
||||
import { HexclaveCompanion } from "@/components/stack-companion";
|
||||
import ThemeToggle from "@/components/theme-toggle";
|
||||
import {
|
||||
Button,
|
||||
@ -769,7 +769,7 @@ export default function SidebarLayout(props: { children?: React.ReactNode }) {
|
||||
|
||||
{/* Stack Companion - overlay with reserved content gutter */}
|
||||
<div className="pointer-events-none absolute top-0 right-2 bottom-0 z-30 hidden lg:block">
|
||||
<StackCompanion className="pointer-events-auto" glassBg={isCustomDashboardPage} />
|
||||
<HexclaveCompanion className="pointer-events-auto" glassBg={isCustomDashboardPage} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { getStackServerApp } from "@/stack/server";
|
||||
import { getHexclaveServerApp } from "@/stack/server";
|
||||
import { getEnvVariable } from "@hexclave/shared/dist/utils/env";
|
||||
import { getOrCreateFeaturebaseUser } from "@hexclave/shared/dist/utils/featurebase";
|
||||
import { urlString } from "@hexclave/shared/dist/utils/urls";
|
||||
@ -21,7 +21,7 @@ export default async function FeaturebaseSSO({
|
||||
return <div>Missing return_to parameter. Please go back and try again.</div>;
|
||||
}
|
||||
|
||||
const user = await getStackServerApp().getUser();
|
||||
const user = await getHexclaveServerApp().getUser();
|
||||
if (!user) {
|
||||
redirect(urlString`/handler/sign-in?after_auth_return_to=${urlString`/integrations/featurebase/sso?return_to=${returnTo}`}`);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { getStackServerApp } from "@/stack/server";
|
||||
import { getHexclaveServerApp } from "@/stack/server";
|
||||
import { getEnvVariable } from "@hexclave/shared/dist/utils/env";
|
||||
import { HexclaveAssertionError } from "@hexclave/shared/dist/utils/errors";
|
||||
import { redirect } from "next/navigation";
|
||||
@ -18,7 +18,7 @@ export default async function IntegrationConfirmPage(props: {
|
||||
const onContinue = async (options: { projectId: string, projectName?: string }) => {
|
||||
"use server";
|
||||
|
||||
const user = await getStackServerApp().getUser();
|
||||
const user = await getHexclaveServerApp().getUser();
|
||||
if (!user) {
|
||||
return { error: "unauthorized" };
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import { SiteLoadingIndicatorDisplay } from "@/components/site-loading-indicator
|
||||
import { Toaster } from "@/components/ui";
|
||||
import { VersionAlerter } from "@/components/version-alerter";
|
||||
import { getPublicEnvVar } from "@/lib/env";
|
||||
import { stackClientApp } from "@/stack/client";
|
||||
import { hexclaveClientApp } from "@/stack/client";
|
||||
import { StackProvider, StackTheme } from "@hexclave/next";
|
||||
import { runAsynchronouslyWithAlert } from "@hexclave/shared/dist/utils/promises";
|
||||
import React, { useSyncExternalStore } from "react";
|
||||
@ -166,7 +166,7 @@ export function LayoutClient(props: {
|
||||
}) {
|
||||
return (
|
||||
<>
|
||||
<StackProvider app={stackClientApp} lang={props.translationLocale as React.ComponentProps<typeof StackProvider>["lang"]}>
|
||||
<StackProvider app={hexclaveClientApp} lang={props.translationLocale as React.ComponentProps<typeof StackProvider>["lang"]}>
|
||||
<StackTheme>
|
||||
<ClientPolyfill />
|
||||
<DevEnvironmentHealthGate>
|
||||
|
||||
@ -105,22 +105,22 @@ const CLOSE_THRESHOLD = 100;
|
||||
const SPLIT_SCREEN_BREAKPOINT = 1000;
|
||||
|
||||
// Context for sharing companion state with layout
|
||||
type StackCompanionContextType = {
|
||||
type HexclaveCompanionContextType = {
|
||||
drawerWidth: number,
|
||||
isSplitScreenMode: boolean,
|
||||
};
|
||||
|
||||
const StackCompanionContext = createContext<StackCompanionContextType>({
|
||||
const HexclaveCompanionContext = createContext<HexclaveCompanionContextType>({
|
||||
drawerWidth: 0,
|
||||
isSplitScreenMode: false,
|
||||
});
|
||||
|
||||
export function useStackCompanion() {
|
||||
return useContext(StackCompanionContext);
|
||||
export function useHexclaveCompanion() {
|
||||
return useContext(HexclaveCompanionContext);
|
||||
}
|
||||
|
||||
|
||||
export function StackCompanion({ className, glassBg = false }: { className?: string, glassBg?: boolean }) {
|
||||
export function HexclaveCompanion({ className, glassBg = false }: { className?: string, glassBg?: boolean }) {
|
||||
const [activeItem, setActiveItem] = useState<string | null>(null);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [versionCheckResult, setVersionCheckResult] = useState<VersionCheckResult>(null);
|
||||
@ -524,7 +524,7 @@ export function StackCompanion({ className, glassBg = false }: { className?: str
|
||||
|
||||
if (isSplitScreenMode) {
|
||||
return (
|
||||
<StackCompanionContext.Provider value={contextValue}>
|
||||
<HexclaveCompanionContext.Provider value={contextValue}>
|
||||
<aside
|
||||
className={cn(
|
||||
"sticky top-14 h-[calc(100vh-3.5rem)] dark:top-20 dark:h-[calc(100vh-6rem)] mr-3 flex flex-row-reverse items-stretch shrink-0",
|
||||
@ -553,7 +553,7 @@ export function StackCompanion({ className, glassBg = false }: { className?: str
|
||||
{/* Handle */}
|
||||
{handleComponent}
|
||||
</aside>
|
||||
</StackCompanionContext.Provider>
|
||||
</HexclaveCompanionContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
@ -562,7 +562,7 @@ export function StackCompanion({ className, glassBg = false }: { className?: str
|
||||
const showDrawerContainer = isOpen || isAnimating;
|
||||
|
||||
return (
|
||||
<StackCompanionContext.Provider value={contextValue}>
|
||||
<HexclaveCompanionContext.Provider value={contextValue}>
|
||||
{/* Main Container - Fixed Right Edge, Flex Reverse to push handle left */}
|
||||
<div className={cn("fixed inset-y-0 right-0 z-50 flex flex-row-reverse items-center pointer-events-none", className)}>
|
||||
|
||||
@ -584,6 +584,6 @@ export function StackCompanion({ className, glassBg = false }: { className?: str
|
||||
{/* 2. Stack Companion Handle (Left of Drawer) */}
|
||||
{handleComponent}
|
||||
</div>
|
||||
</StackCompanionContext.Provider>
|
||||
</HexclaveCompanionContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ export function shouldDisplayVersionResult(
|
||||
|
||||
/**
|
||||
* Common utility function for checking version against Hexclave API
|
||||
* Used by both VersionAlerter and StackCompanion components
|
||||
* Used by both VersionAlerter and HexclaveCompanion components
|
||||
*/
|
||||
export function checkVersion(
|
||||
onResult: (result: VersionCheckResult) => void,
|
||||
|
||||
@ -10,7 +10,7 @@ if (getPublicEnvVar("NEXT_PUBLIC_STACK_PROJECT_ID") !== "internal") {
|
||||
const isPreview = getPublicEnvVar("NEXT_PUBLIC_STACK_IS_PREVIEW") === "true";
|
||||
const isRemoteDevelopmentEnvironment = getPublicEnvVar("NEXT_PUBLIC_STACK_IS_REMOTE_DEVELOPMENT_ENVIRONMENT") === "true";
|
||||
|
||||
export const stackClientApp = new StackClientApp({
|
||||
export const hexclaveClientApp = new StackClientApp({
|
||||
baseUrl: {
|
||||
browser: getPublicEnvVar("NEXT_PUBLIC_BROWSER_STACK_API_URL") ?? getPublicEnvVar("NEXT_PUBLIC_STACK_API_URL") ?? throwErr("NEXT_PUBLIC_BROWSER_STACK_API_URL is not set"),
|
||||
server: getPublicEnvVar("NEXT_PUBLIC_SERVER_STACK_API_URL") ?? getPublicEnvVar("NEXT_PUBLIC_STACK_API_URL") ?? throwErr("NEXT_PUBLIC_SERVER_STACK_API_URL is not set"),
|
||||
|
||||
@ -3,18 +3,18 @@ import "server-only";
|
||||
import { isRemoteDevelopmentEnvironmentEnabled } from "@/lib/remote-development-environment/env";
|
||||
import { StackServerApp } from "@hexclave/next";
|
||||
import { HexclaveAssertionError } from "@hexclave/shared/dist/utils/errors";
|
||||
import { stackClientApp } from "./client";
|
||||
import { hexclaveClientApp } from "./client";
|
||||
|
||||
type InternalServerApp = StackServerApp<true, "internal">;
|
||||
let _stackServerApp: InternalServerApp | undefined;
|
||||
|
||||
export function getStackServerApp(): InternalServerApp {
|
||||
export function getHexclaveServerApp(): InternalServerApp {
|
||||
if (!_stackServerApp) {
|
||||
if (isRemoteDevelopmentEnvironmentEnabled()) {
|
||||
throw new HexclaveAssertionError("stackServerApp is not available in the local remote development environment dashboard.");
|
||||
}
|
||||
_stackServerApp = new StackServerApp({
|
||||
inheritsFrom: stackClientApp,
|
||||
inheritsFrom: hexclaveClientApp,
|
||||
});
|
||||
}
|
||||
return _stackServerApp;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
import { Suspense } from "react";
|
||||
import { StackProvider, StackTheme } from "@hexclave/next";
|
||||
import { stackClientApp } from "../stack";
|
||||
import { hexclaveClientApp } from "../stack";
|
||||
import Loading from "./loading";
|
||||
import "./globals.css";
|
||||
|
||||
@ -13,7 +13,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
||||
<title>Hexclave — MCP Review Tool</title>
|
||||
</head>
|
||||
<body>
|
||||
<StackProvider app={stackClientApp}>
|
||||
<StackProvider app={hexclaveClientApp}>
|
||||
<StackTheme>
|
||||
<Suspense fallback={<Loading />}>
|
||||
{children}
|
||||
|
||||
@ -22,7 +22,7 @@ const publishableClientKey = envOrDevDefault(
|
||||
);
|
||||
const apiUrl = envOrDevDefault(process.env.NEXT_PUBLIC_STACK_API_URL, `http://localhost:${portPrefix}02`);
|
||||
|
||||
export const stackClientApp = new StackClientApp({
|
||||
export const hexclaveClientApp = new StackClientApp({
|
||||
projectId,
|
||||
publishableClientKey,
|
||||
tokenStore: "cookie",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const { StackHandler } = require("@hexclave/next");
|
||||
const { stackServerApp } = require("../../../stack");
|
||||
const { stackServerApp } = require("../../../hexclave");
|
||||
|
||||
function Handler(props) {
|
||||
return <StackHandler fullPage app={stackServerApp} routeProps={props} />;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
const { StackProvider, StackTheme } = require("@hexclave/next");
|
||||
const { stackServerApp } = require("../stack");
|
||||
const { stackServerApp } = require("../hexclave");
|
||||
require("./globals.css");
|
||||
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { StackHandler } from "@hexclave/next";
|
||||
import { stackServerApp } from "../../../stack/server";
|
||||
import { stackServerApp } from "../../../hexclave/server";
|
||||
|
||||
export default function Handler(props: unknown) {
|
||||
return <StackHandler fullPage app = { stackServerApp } routeProps = { props } />;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { Metadata } from "next";
|
||||
import { StackProvider, StackTheme } from "@hexclave/next";
|
||||
import { stackServerApp } from "../stack/server";
|
||||
import { stackServerApp } from "../hexclave/server";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import ConvexClientProvider from "@/components/ConvexClientProvider";
|
||||
|
||||
@ -2,7 +2,7 @@ import Home from "./inner";
|
||||
import { preloadQuery, preloadedQueryResult } from "convex/nextjs";
|
||||
import { api } from "@/convex/_generated/api";
|
||||
import { ConvexHttpClient } from "convex/browser";
|
||||
import { stackServerApp } from "@/stack/server";
|
||||
import { stackServerApp } from "@/hexclave/server";
|
||||
|
||||
export default async function ServerPage() {
|
||||
const preloaded = await preloadQuery(api.myFunctions.listNumbers, {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { api } from "@/convex/_generated/api";
|
||||
import { stackClientApp } from "@/stack/client";
|
||||
import { stackClientApp } from "@/hexclave/client";
|
||||
import { ConvexHttpClient, ConvexClient } from "convex/browser";
|
||||
|
||||
const convexHttpClient = new ConvexHttpClient(process.env.NEXT_PUBLIC_CONVEX_URL!);
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { stackClientApp } from "@/stack/client";
|
||||
import { stackClientApp } from "@/hexclave/client";
|
||||
import { ConvexProvider, ConvexReactClient } from "convex/react";
|
||||
import { ReactNode } from "react";
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
"use node"
|
||||
|
||||
import { v } from "convex/values";
|
||||
import { stackServerApp } from "../stack/server";
|
||||
import { stackServerApp } from "../hexclave/server";
|
||||
import { action } from "./_generated/server";
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
|
||||
import { v } from "convex/values";
|
||||
import { stackClientApp } from "../stack/client";
|
||||
import { stackServerApp } from "../stack/server";
|
||||
import { stackClientApp } from "../hexclave/client";
|
||||
import { stackServerApp } from "../hexclave/server";
|
||||
import { action, mutation, query } from "./_generated/server";
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { ServerTeam, ServerUser } from "@hexclave/next";
|
||||
import { NextResponse } from "next/server";
|
||||
import { stackServerApp } from "src/stack";
|
||||
import { stackServerApp } from "src/hexclave";
|
||||
export async function POST(request: Request) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { stackServerApp } from "src/stack";
|
||||
import { stackServerApp } from "src/hexclave";
|
||||
import { FallbackTestClient } from "./client";
|
||||
|
||||
export default async function FallbackTestPage() {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { StackHandler } from "@hexclave/next";
|
||||
import { stackServerApp } from "src/stack";
|
||||
import { stackServerApp } from "src/hexclave";
|
||||
|
||||
export default function Handler(props) {
|
||||
return (
|
||||
|
||||
@ -3,7 +3,7 @@ import { Metadata } from "next";
|
||||
import React from "react";
|
||||
import Header from "src/components/header";
|
||||
import Provider from "src/components/provider";
|
||||
import { stackServerApp } from "src/stack";
|
||||
import { stackServerApp } from "src/hexclave";
|
||||
import './global.css';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { branchConfigSchema, getConfigOverrideErrors } from "@hexclave/shared/dist/config/schema";
|
||||
import { ITEM_IDS, PLAN_LIMITS } from "@hexclave/shared/dist/plans";
|
||||
import { NextResponse } from "next/server";
|
||||
import { stackServerApp } from "src/stack";
|
||||
import { stackServerApp } from "src/hexclave";
|
||||
|
||||
function readValidationResult(result: Awaited<ReturnType<typeof getConfigOverrideErrors>>) {
|
||||
if (result.status === "ok") {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { stackServerApp } from "src/stack";
|
||||
import { stackServerApp } from "src/hexclave";
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === "object" && value !== null && !Array.isArray(value);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { stackServerApp } from "src/stack";
|
||||
import { stackServerApp } from "src/hexclave";
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === "object" && value !== null && !Array.isArray(value);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { stackServerApp } from "src/stack";
|
||||
import { stackServerApp } from "src/hexclave";
|
||||
|
||||
export default async function ProtectedPage() {
|
||||
await stackServerApp.getUser({ or: 'redirect' });
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { stackServerApp } from "src/stack";
|
||||
import { stackServerApp } from "src/hexclave";
|
||||
|
||||
export default async function Page() {
|
||||
const user = await stackServerApp.getUser({ or: 'redirect' });
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { StackHandler } from "@hexclave/next";
|
||||
import { stackServerApp } from "src/stack";
|
||||
import { stackServerApp } from "src/hexclave";
|
||||
|
||||
export default function Handler(props) {
|
||||
return <StackHandler fullPage app={stackServerApp} routeProps={props} />;
|
||||
|
||||
@ -2,7 +2,7 @@ import { StackProvider } from "@hexclave/next";
|
||||
import { Metadata } from "next";
|
||||
import { Inter } from 'next/font/google';
|
||||
import Provider from "src/components/provider";
|
||||
import { stackServerApp } from "src/stack";
|
||||
import { stackServerApp } from "src/hexclave";
|
||||
import './global.css';
|
||||
|
||||
const inter = Inter({ subsets: ['latin'] });
|
||||
|
||||
@ -3,7 +3,7 @@ import "server-only";
|
||||
import Link from 'next/link';
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { randomUUID } from "crypto";
|
||||
import { stackServerApp } from '@/stack';
|
||||
import { stackServerApp } from '@/hexclave';
|
||||
import { Product, Shop } from "@/shop";
|
||||
|
||||
export default async function EditShop() {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { StackHandler } from "@hexclave/next";
|
||||
import { stackServerApp } from "../../../stack";
|
||||
import { stackServerApp } from "../../../hexclave";
|
||||
|
||||
export default function Handler(props: any) {
|
||||
return <StackHandler fullPage app={stackServerApp} routeProps={props} />;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import { StackProvider, StackTheme } from "@hexclave/next";
|
||||
import { Inter } from "next/font/google";
|
||||
import { stackServerApp } from "../stack";
|
||||
import { stackServerApp } from "../hexclave";
|
||||
import "./globals.css";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { ServerUser } from "@hexclave/next";
|
||||
import { Shop } from "@/shop";
|
||||
import { stackServerApp } from "@/stack";
|
||||
import { stackServerApp } from "@/hexclave";
|
||||
|
||||
export default async function Home() {
|
||||
const users = await stackServerApp.listUsers();
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { stackClientApp } from "./stack";
|
||||
import { stackClientApp } from "./hexclave";
|
||||
|
||||
const updateUIState = (user: any | null) => {
|
||||
const authOptions = document.getElementById("authOptions");
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { stackClientApp } from "./stack";
|
||||
import { stackClientApp } from "./hexclave";
|
||||
|
||||
// Check if user is already signed in
|
||||
stackClientApp.getUser().then((user) => {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { stackClientApp } from "./stack";
|
||||
import { stackClientApp } from "./hexclave";
|
||||
|
||||
// Check if user is already signed in
|
||||
stackClientApp.getUser().then((user) => {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { stackClientApp } from "./stack";
|
||||
import { stackClientApp } from "./hexclave";
|
||||
|
||||
// Check if user is already signed in
|
||||
stackClientApp.getUser().then((user) => {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { stackClientApp } from "./stack";
|
||||
import { stackClientApp } from "./hexclave";
|
||||
|
||||
// Check if user is already signed in
|
||||
stackClientApp.getUser().then((user) => {
|
||||
|
||||
@ -6,7 +6,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { BrowserRouter, Route, Routes, useLocation } from "react-router-dom";
|
||||
import Index from "./pages/Index";
|
||||
import NotFound from "./pages/NotFound";
|
||||
import { stackClientApp } from "./stack/client";
|
||||
import { stackClientApp } from "./hexclave/client";
|
||||
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { StackHandler } from "@hexclave/next";
|
||||
import { stackServerApp } from "../../../stack";
|
||||
import { stackServerApp } from "../../../hexclave";
|
||||
|
||||
export default function Handler(props: any) {
|
||||
return (
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import type { Metadata } from "next";
|
||||
import { StackProvider, StackTheme } from "@hexclave/next";
|
||||
import { stackServerApp } from "../stack";
|
||||
import { stackServerApp } from "../hexclave";
|
||||
import { Inter } from "next/font/google";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { stackServerApp } from "@/stack";
|
||||
import { stackServerApp } from "@/hexclave";
|
||||
import Link from "next/link";
|
||||
|
||||
export default async function Home() {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { stackServerApp } from "@/stack";
|
||||
import { stackServerApp } from "@/hexclave";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function Home() {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
import type { NextRequest } from 'next/server';
|
||||
import { stackServerApp } from './stack';
|
||||
import { stackServerApp } from './hexclave';
|
||||
|
||||
export async function middleware(request: NextRequest) {
|
||||
console.log('Running middleware on URL: ', request.url);
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { StackHandler, StackProvider, StackTheme } from "@hexclave/react";
|
||||
import { Suspense } from "react";
|
||||
import { BrowserRouter, Route, Routes, useLocation } from "react-router-dom";
|
||||
import { stackClientApp } from "./stack";
|
||||
import { stackClientApp } from "./hexclave";
|
||||
|
||||
function HandlerRoutes() {
|
||||
const location = useLocation();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { StackHandler } from "@hexclave/next";
|
||||
import { stackServerApp } from "../../../stack";
|
||||
import { stackServerApp } from "../../../hexclave";
|
||||
|
||||
export default function Handler(props: any) {
|
||||
return <StackHandler fullPage app={stackServerApp} routeProps={props} />;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { StackProvider, StackTheme } from "@hexclave/next";
|
||||
import { stackServerApp } from "../stack";
|
||||
import { stackServerApp } from "../hexclave";
|
||||
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use server';
|
||||
|
||||
import { stackServerApp } from "@/stack";
|
||||
import { stackServerApp } from "@/hexclave";
|
||||
import * as jose from "jose";
|
||||
|
||||
/*
|
||||
|
||||
@ -6,7 +6,7 @@ import { createRootRoute, HeadContent, Outlet, Scripts } from "@tanstack/react-r
|
||||
import type { ReactNode } from "react";
|
||||
import { Suspense, useMemo } from "react";
|
||||
import { Header } from "~/components/header";
|
||||
import { createStackApp } from "~/stack";
|
||||
import { createStackApp } from "~/hexclave";
|
||||
|
||||
export const Route = createRootRoute({
|
||||
head: () => ({
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
import { decodeBase64, encodeBase64 } from "../../utils/bytes";
|
||||
import { decrypt, encrypt, hash, iteratedHash } from "../../utils/crypto";
|
||||
|
||||
// NOTE (Hexclave rebrand): do NOT rename these "stack-*" purpose tags. They are mixed into the
|
||||
// vault's key derivation and value encryption; renaming any of them would make every
|
||||
// previously-stored vault value undecryptable. Internal constants, never user-visible.
|
||||
const hashPurpose = "stack-data-vault-client-side-encryption-key-hash";
|
||||
const encryptionSecretPurpose = "stack-data-vault-client-side-encryption-value-encryption-key-hash";
|
||||
const encryptionValuePurpose = "stack-data-vault-client-side-encryption-value-encryption-value-encryption";
|
||||
|
||||
@ -79,6 +79,9 @@ async function getKmsClient() {
|
||||
}
|
||||
|
||||
async function getOrCreateKekId(): Promise<string> {
|
||||
// NOTE (Hexclave rebrand): do NOT rename this "stack-*" alias. It is the AWS KMS key alias for
|
||||
// the existing key-encryption key; renaming it would point at a non-existent key and break
|
||||
// wrap/unwrap of all stored data keys. Internal infrastructure constant, never user-visible.
|
||||
const id = "alias/stack-data-vault-server-side-kek";
|
||||
const kms = await getKmsClient();
|
||||
try {
|
||||
@ -123,6 +126,8 @@ export async function encryptWithKms(value: string) {
|
||||
const { dekBytes, edkBytes } = await genDEK();
|
||||
try {
|
||||
const ciphertext = await encrypt({
|
||||
// NOTE (Hexclave rebrand): do NOT rename this "stack-*" purpose tag — it must match the one
|
||||
// used in decryptWithKms below, or already-encrypted values become undecryptable.
|
||||
purpose: "stack-data-vault-server-side-encryption",
|
||||
secret: dekBytes,
|
||||
value: new TextEncoder().encode(value),
|
||||
|
||||
@ -34,6 +34,9 @@ async function getDerivedSymmetricKey(purpose: string, secret: string | Uint8Arr
|
||||
name: "HKDF",
|
||||
salt: toArrayBufferBacked(salt),
|
||||
hash: "SHA-256",
|
||||
// NOTE (Hexclave rebrand): do NOT rename this "stack-*" literal. It is a domain-separation
|
||||
// tag baked into HKDF key derivation; changing it would derive different keys and make all
|
||||
// previously-encrypted data undecryptable. It is an internal constant, never user-visible.
|
||||
info: new TextEncoder().encode(JSON.stringify([
|
||||
"stack-crypto-helper-derived-symmetric-key",
|
||||
purpose,
|
||||
@ -126,6 +129,9 @@ export async function iteratedHash(options: HashOptions & { iterations: number }
|
||||
);
|
||||
return new Uint8Array(await crypto.subtle.deriveBits({
|
||||
name: "PBKDF2",
|
||||
// NOTE (Hexclave rebrand): do NOT rename this "stack-*" literal. It is a domain-separation tag
|
||||
// mixed into the PBKDF2 salt; changing it would change every hash output and break verification
|
||||
// of all previously-hashed values. It is an internal constant, never user-visible.
|
||||
salt: new TextEncoder().encode(JSON.stringify([
|
||||
"stack-crypto-helper-iterated-hash",
|
||||
options.purpose,
|
||||
|
||||
@ -111,6 +111,9 @@ export async function getPrivateJwks(options: {
|
||||
}]))
|
||||
.digest()
|
||||
);
|
||||
// NOTE (Hexclave rebrand): do NOT rename these "stack-*" literals. They are hashed into the
|
||||
// per-audience JWT signing secret and key id (kid); renaming them would rotate every project's
|
||||
// JWKS and invalidate all already-issued access tokens. Internal constants, never user-visible.
|
||||
const perAudienceSecret = getHashOfJwkInfo("stack-jwk-audience-secret");
|
||||
const perAudienceKid = getHashOfJwkInfo("stack-jwk-kid").slice(0, 12);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user