diff --git a/package.json b/package.json index 3e96285a706..32515952b36 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,8 @@ "bentocache": "patches/bentocache.patch", "nextra": "patches/nextra.patch", "nextra-theme-docs": "patches/nextra-theme-docs.patch", - "@graphql-codegen/schema-ast": "patches/@graphql-codegen__schema-ast.patch" + "@graphql-codegen/schema-ast": "patches/@graphql-codegen__schema-ast.patch", + "@better-auth/core": "patches/@better-auth__core.patch" } } } diff --git a/packages/migrations/src/actions/2025.10.24T00-00-00.better-auth.ts b/packages/migrations/src/actions/2025.10.24T00-00-00.better-auth.ts new file mode 100644 index 00000000000..25ae7d6e060 --- /dev/null +++ b/packages/migrations/src/actions/2025.10.24T00-00-00.better-auth.ts @@ -0,0 +1,140 @@ +import { type MigrationExecutor } from '../pg-migrator'; + +/** + * Initializes DB for Better Auth and migrates SuperTokens auth data to it + */ +export default { + name: '2025.10.24T00-00-00.better-auth.ts', + noTransaction: true, + run: ({ sql }) => [ + { + name: 'Setup better-auth tables', + query: sql` + CREATE TABLE IF NOT EXISTS "better_auth_users" ( + "id" text NOT NULL PRIMARY KEY + , "name" text NOT NULL + , "email" text NOT NULL UNIQUE + , "emailVerified" boolean NOT NULL DEFAULT FALSE + , "image" text + , "createdAt" timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL + , "updatedAt" timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL + ); + + CREATE TABLE IF NOT EXISTS "better_auth_sessions" ( + "id" text NOT NULL PRIMARY KEY + , "expiresAt" timestamptz NOT NULL + , "token" text NOT NULL UNIQUE + , "createdAt" timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL + , "updatedAt" timestamptz NOT NULL + , "ipAddress" text + , "userAgent" text + , "userId" text NOT NULL REFERENCES "better_auth_users" ("id") ON DELETE CASCADE + ); + + CREATE TABLE IF NOT EXISTS "better_auth_accounts" ( + "id" text NOT NULL PRIMARY KEY + , "accountId" text NOT NULL + , "providerId" text NOT NULL + , "userId" text NOT NULL REFERENCES "better_auth_users" ("id") ON DELETE CASCADE + , "accessToken" text + , "refreshToken" text + , "idToken" text + , "accessTokenExpiresAt" timestamptz + , "refreshTokenExpiresAt" timestamptz + , "scope" text + , "password" text + , "createdAt" timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL + , "updatedAt" timestamptz NOT NULL + ); + + CREATE TABLE IF NOT EXISTS "better_auth_verifications" ( + "id" text NOT NULL PRIMARY KEY + , "identifier" text NOT NULL + , "value" text NOT NULL + , "expiresAt" timestamptz NOT NULL + , "createdAt" timestamptz DEFAULT CURRENT_TIMESTAMP NOT NULL + , "updatedAt" timestamptz NOT NULL + ); + + CREATE TABLE IF NOT EXISTS "better_auth_sso_providers" ( + "id" text NOT NULL PRIMARY KEY + , "issuer" text NOT NULL + , "oidcConfig" text + , "samlConfig" text + , "userId" text NOT NULL REFERENCES "better_auth_users" ("id") ON DELETE CASCADE + , "providerId" text NOT NULL UNIQUE + , "organizationId" text + , "domain" text NOT NULL + ); + `, + }, + { + name: 'Migrate emailpassword users and accounts', + query: sql` + INSERT INTO "better_auth_users" + ("id", "name", "email", "createdAt") + SELECT + "sepu"."user_id" AS "id", + "u"."full_name" AS "name", + "sepu"."email" AS "email", + TO_TIMESTAMP("sepu"."time_joined" / 1000.0) AS "createdAt" + FROM "supertokens_emailpassword_users" "sepu" + INNER JOIN "users" "u" + ON "sepu"."user_id" = "u"."supertoken_user_id" + ON CONFLICT DO NOTHING; + + INSERT INTO "better_auth_accounts" + ("id", "accountId", "providerId", "userId", "password", "createdAt", "updatedAt") + SELECT + REPLACE(uuid_generate_v4()::text, '-', '') AS "id", + "sepu"."user_id" AS "accountId", + 'credential' AS "providerId", + "sepu"."user_id" AS "userId", + "sepu"."password_hash" AS "password", + TO_TIMESTAMP("sepu"."time_joined" / 1000.0) AS "createdAt", + CURRENT_TIMESTAMP AS "updatedAt" + FROM "supertokens_emailpassword_users" "sepu" + INNER JOIN "users" "u" + ON "sepu"."user_id" = "u"."supertoken_user_id"; + `, + }, + { + name: "Migrate thirdparty users and accounts", + query: sql` + INSERT INTO "better_auth_users" + ("id", "name", "email", "createdAt") + SELECT + "stpu"."user_id" AS "id", + "u"."full_name" AS "name", + "stpu"."email" AS "email", + TO_TIMESTAMP("stpu"."time_joined" / 1000.0) AS "createdAt" + FROM "supertokens_thirdparty_users" "stpu" + INNER JOIN "users" "u" + ON "stpu"."user_id" = "u"."supertoken_user_id"; + + INSERT INTO "better_auth_accounts" + ("id", "accountId", "providerId", "userId", "createdAt", "updatedAt") + SELECT + REPLACE(uuid_generate_v4()::text, '-', '') AS "id", + "stpu"."third_party_user_id" AS "accountId", + "stpu"."third_party_id" AS "providerId", + "stpu"."user_id" AS "userId", + TO_TIMESTAMP("supertokens_thirdparty_users"."time_joined" / 1000.0) AS "createdAt", + CURRENT_TIMESTAMP AS "updatedAt" + FROM "supertokens_thirdparty_users" "stpu" + INNER JOIN "users" "u" + ON "stpu"."user_id" = "u"."supertoken_user_id"; + `, + }, + { + name: 'Migrate email verifications', + query: sql` + UPDATE "better_auth_users" "bau" + SET "emailVerified" = TRUE + WHERE "bau"."email" IN ( + SELECT "email" FROM "supertokens_emailverification_verified_emails" + ); + `, + }, + ], +} satisfies MigrationExecutor; diff --git a/packages/services/api/src/create.ts b/packages/services/api/src/create.ts index 9f9389d8f0d..b67e47209db 100644 --- a/packages/services/api/src/create.ts +++ b/packages/services/api/src/create.ts @@ -10,6 +10,7 @@ import { AuditLogRecorder } from './modules/audit-logs/providers/audit-log-recor import { AuditLogS3Config } from './modules/audit-logs/providers/audit-logs-manager'; import { authModule } from './modules/auth'; import { Session } from './modules/auth/lib/authz'; +import { AuthInstance, provideAuthInstance } from './modules/auth/providers/auth-instance'; import { cdnModule } from './modules/cdn'; import { AwsClient } from './modules/cdn/providers/aws'; import { CDN_CONFIG, CDNConfig } from './modules/cdn/providers/tokens'; @@ -114,6 +115,7 @@ export function createRegistry({ pubSub, appDeploymentsEnabled, prometheus, + authInstance, }: { logger: Logger; storage: Storage; @@ -158,6 +160,7 @@ export function createRegistry({ pubSub: HivePubSub; appDeploymentsEnabled: boolean; prometheus: null | Record; + authInstance: AuthInstance; }) { const s3Config: S3Config = [ { @@ -298,6 +301,7 @@ export function createRegistry({ encryptionSecretProvider(encryptionSecret), provideSchemaModuleConfig(schemaConfig), provideCommerceConfig(commerce), + provideAuthInstance(authInstance), { provide: Session, useFactory(context: { session: Session }) { diff --git a/packages/services/api/src/modules/auth/lib/authz.ts b/packages/services/api/src/modules/auth/lib/authz.ts index f4661b84573..0199e69b5e1 100644 --- a/packages/services/api/src/modules/auth/lib/authz.ts +++ b/packages/services/api/src/modules/auth/lib/authz.ts @@ -92,7 +92,7 @@ export abstract class Session { /** * Retrieve the Viewer of the session. - * A viewer can only be a {User} aka {SuperTokensSessions{}. + * A viewer can only be a {User}. * If the session does not have a user an exception is raised. */ public async getViewer(): Promise { @@ -539,7 +539,7 @@ class UnauthenticatedSession extends Session { /** * Strategy to authenticate a session from an incoming request. - * E.g. SuperTokens, JWT, etc. + * E.g. Better Auth, JWT, etc. */ export abstract class AuthNStrategy { /** diff --git a/packages/services/api/src/modules/auth/lib/better-auth-strategy.ts b/packages/services/api/src/modules/auth/lib/better-auth-strategy.ts new file mode 100644 index 00000000000..780c25e6ed7 --- /dev/null +++ b/packages/services/api/src/modules/auth/lib/better-auth-strategy.ts @@ -0,0 +1,243 @@ +import type { FastifyReply, FastifyRequest } from '@hive/service-common'; +import { captureException } from '@sentry/node'; +import { AccessError, HiveError } from '../../../shared/errors'; +import { isUUID } from '../../../shared/is-uuid'; +import { OrganizationMembers } from '../../organization/providers/organization-members'; +import { Logger } from '../../shared/providers/logger'; +import type { Storage } from '../../shared/providers/storage'; +import { AuthInstance } from '../providers/auth-instance'; +import { AuthNStrategy, AuthorizationPolicyStatement, Session, UserActor } from './authz'; + +export class BetterAuthCookieBasedSession extends Session { + public betterAuthUserId: string; + private organizationMembers: OrganizationMembers; + private storage: Storage; + + constructor( + args: { betterAuthUserId: string; email: string }, + deps: { organizationMembers: OrganizationMembers; storage: Storage; logger: Logger }, + ) { + super({ logger: deps.logger }); + this.betterAuthUserId = args.betterAuthUserId; + this.organizationMembers = deps.organizationMembers; + this.storage = deps.storage; + } + + get id(): string { + return this.betterAuthUserId; + } + + protected async loadPolicyStatementsForOrganization( + organizationId: string, + ): Promise> { + const { user } = await this.getActor(); + + this.logger.debug( + 'Loading policy statements for organization. (userId=%s, organizationId=%s)', + user.id, + organizationId, + ); + + if (!isUUID(organizationId)) { + this.logger.debug( + 'Invalid organization ID provided. (userId=%s, organizationId=%s)', + user.id, + organizationId, + ); + + return []; + } + + this.logger.debug( + 'Load organization membership for user. (userId=%s, organizationId=%s)', + user.id, + organizationId, + ); + const organization = await this.storage.getOrganization({ organizationId }); + const organizationMembership = await this.organizationMembers.findOrganizationMembership({ + organization, + userId: user.id, + }); + + if (!organizationMembership) { + this.logger.debug( + 'No membership found, resolve empty policy statements. (userId=%s, organizationId=%s)', + user.id, + organizationId, + ); + + // Allow admins to use all describe actions within foreign organizations + // This makes it much more pleasant to debug. + if (user.isAdmin) { + return [ + { + action: '*:describe', + effect: 'allow', + resource: `hrn:${organizationId}:organization/${organizationId}`, + }, + ]; + } + + return []; + } + + // owner of organization should have full right to do anything. + if (organizationMembership.isOwner) { + this.logger.debug( + 'User is organization owner, resolve admin access policy. (userId=%s, organizationId=%s)', + user.id, + organizationId, + ); + + return [ + { + action: '*', + effect: 'allow', + resource: `hrn:${organizationId}:organization/${organizationId}`, + }, + ]; + } + + this.logger.debug( + 'Translate organization role assignments to policy statements. (userId=%s, organizationId=%s)', + user.id, + organizationId, + ); + + return organizationMembership.assignedRole.authorizationPolicyStatements; + } + + public async getActor(): Promise { + const user = await this.storage.getUserByBetterAuthId({ + betterAuthUserId: this.betterAuthUserId, + }); + + if (!user) { + throw new AccessError('User not found'); + } + + return { + type: 'user', + user, + }; + } + + public isViewer() { + return true; + } +} + +export class BetterAuthUserAuthNStrategy extends AuthNStrategy { + private logger: Logger; + private organizationMembers: OrganizationMembers; + private storage: Storage; + private auth: AuthInstance; + + constructor(deps: { + logger: Logger; + storage: Storage; + organizationMembers: OrganizationMembers; + auth: AuthInstance; + }) { + super(); + this.logger = deps.logger.child({ module: 'BetterAuthUserAuthNStrategy' }); + this.organizationMembers = deps.organizationMembers; + this.storage = deps.storage; + this.auth = deps.auth; + } + + private async verifyBetterAuthSession(args: { req: FastifyRequest; reply: FastifyReply }) { + this.logger.debug('Attempt verifying Better Auth session'); + + const headers = new Headers(); + + for (const [key, value] of Object.entries(args.req.headers)) { + if (!value) { + continue; + } + + const headerValue = Array.isArray(value) ? value[value.length - 1] : value; + headers.set(key, headerValue); + } + + let session: Awaited>; + + try { + session = await this.auth.api.getSession({ + headers, + }); + this.logger.debug('Session resolution ended successfully'); + } catch (error) { + this.logger.debug('Session resolution failed'); + this.logger.error('Error while resolving user'); + console.log(error); + captureException(error); + + throw error; + } + + if (!session) { + this.logger.debug('No session found'); + return null; + } + + if ( + this.auth.options.emailAndPassword.requireEmailVerification && + !session.user.emailVerified + ) { + throw new HiveError('Your account is not verified. Please verify your email address.', { + extensions: { + code: 'VERIFY_EMAIL', + }, + }); + } + + if (session.session.expiresAt.getTime() <= Date.now()) { + throw new HiveError('Invalid session', { + extensions: { + code: 'NEEDS_REFRESH', + }, + }); + } + + const userId = session.user.id; + const email = session.user.email; + + if (!userId || !email) { + this.logger.error('Session payload is invalid'); + this.logger.debug('Session payload: %s', JSON.stringify(session.user)); + this.logger.debug('Email or ID is missing in the session payload'); + throw new HiveError(`Invalid access token provided`); + } + + this.logger.debug('Better Auth session resolved.'); + return { + betterAuthUserId: userId, + email, + }; + } + + async parse(args: { + req: FastifyRequest; + reply: FastifyReply; + }): Promise { + const session = await this.verifyBetterAuthSession(args); + if (!session) { + return null; + } + + this.logger.debug('Better Auth session resolved successfully'); + + return new BetterAuthCookieBasedSession( + { + betterAuthUserId: session.betterAuthUserId, + email: session.email, + }, + { + storage: this.storage, + organizationMembers: this.organizationMembers, + logger: args.req.log, + }, + ); + } +} diff --git a/packages/services/api/src/modules/auth/providers/auth-instance.ts b/packages/services/api/src/modules/auth/providers/auth-instance.ts new file mode 100644 index 00000000000..5c2f073ad58 --- /dev/null +++ b/packages/services/api/src/modules/auth/providers/auth-instance.ts @@ -0,0 +1,12 @@ +import { InjectionToken, ValueProvider } from 'graphql-modules'; +import type { AuthInstance } from '../../../../../server/src/auth'; + +export type { AuthInstance }; +export const AUTH_INSTANCE = new InjectionToken('auth-instance'); + +export function provideAuthInstance(instance: AuthInstance): ValueProvider { + return { + provide: AUTH_INSTANCE, + useValue: instance, + }; +} diff --git a/packages/services/api/src/modules/organization/providers/organization-manager.ts b/packages/services/api/src/modules/organization/providers/organization-manager.ts index 5d75a4c2df9..fd72264204d 100644 --- a/packages/services/api/src/modules/organization/providers/organization-manager.ts +++ b/packages/services/api/src/modules/organization/providers/organization-manager.ts @@ -296,7 +296,6 @@ export class OrganizationManager { slug: string; user: { id: string; - superTokensUserId: string | null; oidcIntegrationId: string | null; }; }) { diff --git a/packages/services/api/src/modules/shared/providers/storage.ts b/packages/services/api/src/modules/shared/providers/storage.ts index b0d2950f25d..b96898f8d18 100644 --- a/packages/services/api/src/modules/shared/providers/storage.ts +++ b/packages/services/api/src/modules/shared/providers/storage.ts @@ -70,7 +70,7 @@ export interface Storage { destroy(): Promise; isReady(): Promise; ensureUserExists(_: { - superTokensUserId: string; + betterAuthUserId: string; email: string; oidcIntegration: null | { id: string; @@ -80,7 +80,7 @@ export interface Storage { lastName: string | null; }): Promise<'created' | 'no_action'>; - getUserBySuperTokenId(_: { superTokensUserId: string }): Promise; + getUserByBetterAuthId(_: { betterAuthUserId: string }): Promise; getUserById(_: { id: string }): Promise; updateUser(_: { id: string; fullName: string; displayName: string }): Promise; diff --git a/packages/services/api/src/shared/entities.ts b/packages/services/api/src/shared/entities.ts index 4acd0904171..1dfbaf611c2 100644 --- a/packages/services/api/src/shared/entities.ts +++ b/packages/services/api/src/shared/entities.ts @@ -342,7 +342,7 @@ export interface User { fullName: string; displayName: string; provider: AuthProviderType; - superTokensUserId: string | null; + betterAuthUserId: string | null; isAdmin: boolean; oidcIntegrationId: string | null; zendeskId: string | null; diff --git a/packages/services/server/.env.template b/packages/services/server/.env.template index 2f724735e9f..adec75f4e1a 100644 --- a/packages/services/server/.env.template +++ b/packages/services/server/.env.template @@ -83,3 +83,6 @@ AUTH_OKTA_CLIENT_SECRET="" OPENTELEMETRY_COLLECTOR_ENDPOINT="" HIVE_ENCRYPTION_SECRET=wowverysecuremuchsecret + +# Better Auth +BETTER_AUTH_SECRET="bubatzbieber6942096420" diff --git a/packages/services/server/better-auth_migrations/2025-10-24T10-31-56.320Z.sql b/packages/services/server/better-auth_migrations/2025-10-24T10-31-56.320Z.sql new file mode 100644 index 00000000000..8458cd71a87 --- /dev/null +++ b/packages/services/server/better-auth_migrations/2025-10-24T10-31-56.320Z.sql @@ -0,0 +1,9 @@ +create table "better_auth_users" ("id" text not null primary key, "name" text not null, "email" text not null unique, "emailVerified" boolean not null, "image" text, "createdAt" timestamptz default CURRENT_TIMESTAMP not null, "updatedAt" timestamptz default CURRENT_TIMESTAMP not null); + +create table "better_auth_sessions" ("id" text not null primary key, "expiresAt" timestamptz not null, "token" text not null unique, "createdAt" timestamptz default CURRENT_TIMESTAMP not null, "updatedAt" timestamptz not null, "ipAddress" text, "userAgent" text, "userId" text not null references "better_auth_users" ("id") on delete cascade); + +create table "better_auth_accounts" ("id" text not null primary key, "accountId" text not null, "providerId" text not null, "userId" text not null references "better_auth_users" ("id") on delete cascade, "accessToken" text, "refreshToken" text, "idToken" text, "accessTokenExpiresAt" timestamptz, "refreshTokenExpiresAt" timestamptz, "scope" text, "password" text, "createdAt" timestamptz default CURRENT_TIMESTAMP not null, "updatedAt" timestamptz not null); + +create table "better_auth_verifications" ("id" text not null primary key, "identifier" text not null, "value" text not null, "expiresAt" timestamptz not null, "createdAt" timestamptz default CURRENT_TIMESTAMP not null, "updatedAt" timestamptz default CURRENT_TIMESTAMP not null); + +create table "ssoProvider" ("id" text not null primary key, "issuer" text not null, "oidcConfig" text, "samlConfig" text, "userId" text not null references "better_auth_users" ("id") on delete cascade, "providerId" text not null unique, "organizationId" text, "domain" text not null); \ No newline at end of file diff --git a/packages/services/server/package.json b/packages/services/server/package.json index 77d960068ea..2b9bd9a34f2 100644 --- a/packages/services/server/package.json +++ b/packages/services/server/package.json @@ -9,6 +9,7 @@ "typecheck": "tsc --noEmit" }, "devDependencies": { + "@better-auth/sso": "^1.3.27", "@envelop/core": "5.0.2", "@envelop/graphql-jit": "8.0.3", "@envelop/graphql-modules": "7.0.1", @@ -36,7 +37,10 @@ "@theguild/federation-composition": "0.20.2", "@trpc/client": "10.45.2", "@trpc/server": "10.45.2", + "@types/bcrypt": "^6.0.0", "@whatwg-node/server": "0.10.5", + "bcrypt": "^6.0.0", + "better-auth": "^1.3.29", "dotenv": "16.4.7", "fastify": "4.29.1", "got": "14.4.7", @@ -44,6 +48,7 @@ "graphql-yoga": "5.13.3", "hyperid": "3.3.0", "ioredis": "5.4.2", + "pg": "8.13.1", "pino-pretty": "11.3.0", "prom-client": "15.1.3", "reflect-metadata": "0.2.2", diff --git a/packages/services/server/src/api.ts b/packages/services/server/src/api.ts index d0188ef90bd..f58a2198fe0 100644 --- a/packages/services/server/src/api.ts +++ b/packages/services/server/src/api.ts @@ -23,7 +23,7 @@ export const internalApiRouter = t.router({ .input( z .object({ - superTokensUserId: z.string().min(1), + betterAuthUserId: z.string().min(1), email: z.string().min(1), oidcIntegrationId: z.union([z.string(), z.null()]), firstName: z.string().min(1).nullable(), diff --git a/packages/services/server/src/auth.ts b/packages/services/server/src/auth.ts new file mode 100644 index 00000000000..a49632aafd4 --- /dev/null +++ b/packages/services/server/src/auth.ts @@ -0,0 +1,159 @@ +import bcrypt from 'bcrypt'; +import { betterAuth } from 'better-auth'; +import { genericOAuth } from 'better-auth/plugins/generic-oauth'; +import { FastifyBaseLogger } from 'fastify'; +import Pg from 'pg'; +import { sso } from '@better-auth/sso'; +import { Storage } from '@hive/api'; +import { EmailsApi } from '@hive/emails'; +import { createTRPCProxyClient, httpLink } from '@trpc/client'; +import { env } from './environment'; + +const pool = new Pg.Pool({ + user: env.postgres.user, + password: env.postgres.password, + database: env.postgres.db, + host: env.postgres.host, + port: env.postgres.port, + ssl: env.postgres.ssl, +}); + +export type AuthInstance = ReturnType; + +export const auth = createAuth(); + +export function createAuth() { + const emailsService = createTRPCProxyClient({ + links: [httpLink({ url: `${env.hiveServices.emails?.endpoint}/trpc` })], + }); + + return betterAuth({ + baseURL: env.graphql.origin, + database: pool, + trustedOrigins: [env.hiveServices.webApp.url], + user: { + modelName: 'better_auth_users', + }, + session: { + modelName: 'better_auth_sessions', + }, + account: { + modelName: 'better_auth_accounts', + }, + verification: { + modelName: 'better_auth_verifications', + }, + ssoProvider: { + modelName: 'better_auth_sso_providers', + }, + emailAndPassword: { + enabled: true, + minPasswordLength: 8, + maxPasswordLength: 99, + requireEmailVerification: env.auth.requireEmailVerification, + password: { + async hash(password) { + return await bcrypt.hash(password, 11); + }, + async verify({ password, hash }) { + return await bcrypt.compare(password, hash); + }, + }, + async sendResetPassword({ user, url }) { + await emailsService.sendPasswordResetEmail.mutate({ + user: { + id: user.id, + email: user.email, + }, + passwordResetLink: url, + }); + }, + }, + emailVerification: { + async sendVerificationEmail({ user, url }) { + await emailsService.sendEmailVerificationEmail.mutate({ + user: { + id: user.id, + email: user.email, + }, + emailVerifyLink: url, + }); + }, + }, + socialProviders: { + google: env.auth.google + ? { + clientId: env.auth.google.clientId, + clientSecret: env.auth.google.clientSecret, + scope: [ + 'https://www.googleapis.com/auth/userinfo.email', + 'https://www.googleapis.com/auth/userinfo.profile', + 'openid', + ], + } + : undefined, + github: env.auth.github + ? { + clientId: env.auth.github.clientId, + clientSecret: env.auth.github.clientSecret, + scope: ['read:user', 'user:email'], + } + : undefined, + }, + plugins: [ + env.organizationOIDC ? sso() : undefined, + env.auth.okta + ? genericOAuth({ + config: [ + { + providerId: 'okta', + clientId: env.auth.okta.clientId, + clientSecret: env.auth.okta.clientSecret, + scopes: ['openid', 'email', 'profile', 'okta.users.read.self'], + authorizationUrl: `${env.auth.okta.endpoint}/oauth2/v1/authorize`, + tokenUrl: `${env.auth.okta.endpoint}/oauth2/v1/token`, + }, + ], + }) + : undefined, + ].filter(v => v != null), + advanced: { + cookiePrefix: 'hive-auth', + }, + }); +} + +type OidcIdLookupResponse = + | { + ok: true; + id: string; + } + | { + ok: false; + title: string; + description: string; + status: number; + }; + +export async function oidcIdLookup( + slug: string, + storage: Storage, + logger: FastifyBaseLogger, +): Promise { + logger.debug('Looking up OIDC integration ID for organization %s', slug); + const oidcId = await storage.getOIDCIntegrationIdForOrganizationSlug({ slug }); + + if (!oidcId) { + return { + ok: false, + title: 'SSO integration not found', + description: 'Your organization lacks an SSO integration or it does not exist.', + status: 404, + }; + } + + return { + ok: true, + id: oidcId, + }; +} diff --git a/packages/services/server/src/environment.ts b/packages/services/server/src/environment.ts index 5ada401dab5..53974466d55 100644 --- a/packages/services/server/src/environment.ts +++ b/packages/services/server/src/environment.ts @@ -1,5 +1,5 @@ import zod from 'zod'; -import { OpenTelemetryConfigurationModel } from '@hive/service-common'; +import { OpenTelemetryConfigurationModel } from '@hive/service-common/src/index'; const isNumberString = (input: unknown) => zod.string().regex(/^\d+$/).safeParse(input).success; @@ -95,11 +95,6 @@ const RedisModel = zod.object({ REDIS_TLS_ENABLED: emptyString(zod.union([zod.literal('1'), zod.literal('0')]).optional()), }); -const SuperTokensModel = zod.object({ - SUPERTOKENS_CONNECTION_URI: zod.string().url(), - SUPERTOKENS_API_KEY: zod.string(), -}); - const GitHubModel = zod.union([ zod.object({ INTEGRATION_GITHUB: emptyString(zod.literal('0').optional()), @@ -265,7 +260,6 @@ const configs = { postgres: PostgresModel.safeParse(processEnv), clickhouse: ClickHouseModel.safeParse(processEnv), redis: RedisModel.safeParse(processEnv), - supertokens: SuperTokensModel.safeParse(processEnv), authGithub: AuthGitHubConfigSchema.safeParse(processEnv), authGoogle: AuthGoogleConfigSchema.safeParse(processEnv), authOkta: AuthOktaConfigSchema.safeParse(processEnv), @@ -311,7 +305,6 @@ const postgres = extractConfig(configs.postgres); const sentry = extractConfig(configs.sentry); const clickhouse = extractConfig(configs.clickhouse); const redis = extractConfig(configs.redis); -const supertokens = extractConfig(configs.supertokens); const authGithub = extractConfig(configs.authGithub); const authGoogle = extractConfig(configs.authGoogle); const authOkta = extractConfig(configs.authOkta); @@ -405,10 +398,6 @@ export const env = { password: redis.REDIS_PASSWORD ?? '', tlsEnabled: redis.REDIS_TLS_ENABLED === '1', }, - supertokens: { - connectionURI: supertokens.SUPERTOKENS_CONNECTION_URI, - apiKey: supertokens.SUPERTOKENS_API_KEY, - }, auth: { github: authGithub.AUTH_GITHUB === '1' diff --git a/packages/services/server/src/graphql-handler.ts b/packages/services/server/src/graphql-handler.ts index c083443d84a..69b82ef5842 100644 --- a/packages/services/server/src/graphql-handler.ts +++ b/packages/services/server/src/graphql-handler.ts @@ -44,10 +44,6 @@ export interface GraphQLHandlerOptions { registry: Registry; signature: string; tracing?: TracingInstance; - supertokens: { - connectionUri: string; - apiKey: string; - }; isProduction: boolean; hiveUsageConfig: HiveUsageConfig; hivePersistedDocumentsConfig: HivePersistedDocumentsConfig; @@ -147,12 +143,14 @@ export function useHiveSentry() { }); }, appendTags: ({ contextValue }) => { - const supertokens_user_id = extractUserId(contextValue as any); + const better_auth_user_id = extractUserId(contextValue as any); const request_id = (contextValue as Context).requestId; return { - supertokens_user_id, + better_auth_user_id, request_id, + // for backward compat + supertokens_user_id: better_auth_user_id, }; }, skip(args) { diff --git a/packages/services/server/src/index.ts b/packages/services/server/src/index.ts index cc673faf4fa..da67ba01025 100644 --- a/packages/services/server/src/index.ts +++ b/packages/services/server/src/index.ts @@ -1,11 +1,6 @@ #!/usr/bin/env node import got from 'got'; import { GraphQLError, stripIgnoredCharacters } from 'graphql'; -import supertokens from 'supertokens-node'; -import { - errorHandler as supertokensErrorHandler, - plugin as supertokensFastifyPlugin, -} from 'supertokens-node/framework/fastify/index.js'; import cors from '@fastify/cors'; import type { FastifyCorsOptionsDelegateCallback } from '@fastify/cors'; import { createRedisEventTarget } from '@graphql-yoga/redis-event-target'; @@ -23,6 +18,7 @@ import { OrganizationMemberRoles, OrganizationMembers, } from '@hive/api'; +import { BetterAuthUserAuthNStrategy } from '@hive/api/modules/auth/lib/better-auth-strategy'; import { HivePubSub } from '@hive/api/modules/shared/providers/pub-sub'; import { createRedisClient } from '@hive/api/modules/shared/providers/redis'; import { TargetsByIdCache } from '@hive/api/modules/target/providers/targets-by-id-cache'; @@ -58,18 +54,17 @@ import { import { createServerAdapter } from '@whatwg-node/server'; import { AuthN } from '../../api/src/modules/auth/lib/authz'; import { OrganizationAccessTokenStrategy } from '../../api/src/modules/auth/lib/organization-access-token-strategy'; -import { SuperTokensUserAuthNStrategy } from '../../api/src/modules/auth/lib/supertokens-strategy'; import { TargetAccessTokenStrategy } from '../../api/src/modules/auth/lib/target-access-token-strategy'; import { OrganizationAccessTokenValidationCache } from '../../api/src/modules/auth/providers/organization-access-token-validation-cache'; import { OrganizationAccessTokensCache } from '../../api/src/modules/organization/providers/organization-access-tokens-cache'; import { internalApiRouter } from './api'; import { asyncStorage } from './async-storage'; +import { createAuth, oidcIdLookup } from './auth'; import { env } from './environment'; import { graphqlHandler } from './graphql-handler'; import { clickHouseElapsedDuration, clickHouseReadDuration } from './metrics'; import { createOtelAuthEndpoint } from './otel-auth-endpoint'; import { createPublicGraphQLHandler } from './public-graphql-handler'; -import { initSupertokens, oidcIdLookup } from './supertokens'; export async function main() { let tracing: TracingInstance | undefined; @@ -128,6 +123,8 @@ export async function main() { await server.register(...tracing.instrumentFastify()); } + const authInstance = createAuth(); + server.addContentTypeParser( 'application/graphql+json', { parseAs: 'string' }, @@ -146,7 +143,6 @@ export async function main() { }, ); - server.setErrorHandler(supertokensErrorHandler()); await server.register(cors, (_: unknown): FastifyCorsOptionsDelegateCallback => { return (req, callback) => { if (req.headers.origin?.startsWith(env.hiveServices.webApp.url)) { @@ -161,7 +157,9 @@ export async function main() { 'graphql-client-version', 'graphql-client-name', 'x-request-id', - ...supertokens.getAllCORSHeaders(), + // Better Auth headers + 'authorization', + 'x-requested-with', ], }); return; @@ -404,6 +402,7 @@ export async function main() { pubSub, appDeploymentsEnabled: env.featureFlags.appDeploymentsEnabled, prometheus: env.prometheus, + authInstance, }); const organizationAccessTokenStrategy = (logger: Logger) => @@ -422,10 +421,6 @@ export async function main() { graphiqlEndpoint: graphqlPath, registry, signature, - supertokens: { - connectionUri: env.supertokens.connectionURI, - apiKey: env.supertokens.apiKey, - }, isProduction: env.environment !== 'development', release: env.release, hiveUsageConfig: env.hive, @@ -435,7 +430,7 @@ export async function main() { authN: new AuthN({ strategies: [ (logger: Logger) => - new SuperTokensUserAuthNStrategy({ + new BetterAuthUserAuthNStrategy({ logger, storage, organizationMembers: new OrganizationMembers( @@ -443,6 +438,7 @@ export async function main() { new OrganizationMemberRoles(storage.pool, logger), logger, ), + auth: authInstance, }), organizationAccessTokenStrategy, (logger: Logger) => @@ -493,20 +489,81 @@ export async function main() { const crypto = new CryptoProvider(env.encryptionSecret); - initSupertokens({ - storage, - crypto, - logger: server.log, - broadcastLog(id, message) { - pubSub.publish('oidcIntegrationLogs', id, { - timestamp: new Date().toISOString(), - message, + await server.register(formDataPlugin); + + const oidcIdLookupSchema = z.object({ + slug: z.string({ + required_error: 'Slug is required', + }), + }); + server.post('/auth-api/oidc-id-lookup', async (req, res) => { + const inputResult = oidcIdLookupSchema.safeParse(req.body); + + if (!inputResult.success) { + captureException(inputResult.error, { + extra: { + path: '/auth-api/oidc-id-lookup', + body: req.body, + }, }); - }, + void res.status(400).send({ + ok: false, + title: 'Invalid input', + description: 'Failed to resolve SSO information due to invalid input.', + status: 400, + } satisfies Awaited>); + return; + } + + const result = await oidcIdLookup(inputResult.data.slug, storage, req.log); + + if (result.ok) { + void res.status(200).send(result); + return; + } + + void res.status(result.status).send(result); + return; }); - await server.register(formDataPlugin); - await server.register(supertokensFastifyPlugin); + server.route({ + method: ['GET', 'POST'], + url: '/auth-api/*', + async handler(request, reply) { + try { + const url = new URL(request.url, `http://${request.headers.host}`); + const headers = new Headers(); + for (const [key, value] of Object.entries(request.headers)) { + if (Array.isArray(value)) { + for (const v of value) { + headers.append(key, v); + } + } else if (value != null) { + headers.append(key, value); + } + } + + const response = await authInstance.handler( + new Request(url.toString(), { + method: request.method, + headers, + body: request.body ? JSON.stringify(request.body) : undefined, + }), + ); + + reply.status(response.status); + for (const [key, value] of response.headers.entries()) { + reply.header(key, value); + } + reply.send(response.body ? await response.text() : null); + } catch (error) { + server.log.error(error); + reply.status(500).send({ + message: 'Internal authentication error', + }); + } + }, + }); await registerTRPC(server, { router: internalApiRouter, @@ -562,41 +619,6 @@ export async function main() { }, }); - const oidcIdLookupSchema = z.object({ - slug: z.string({ - required_error: 'Slug is required', - }), - }); - server.post('/auth-api/oidc-id-lookup', async (req, res) => { - const inputResult = oidcIdLookupSchema.safeParse(req.body); - - if (!inputResult.success) { - captureException(inputResult.error, { - extra: { - path: '/auth-api/oidc-id-lookup', - body: req.body, - }, - }); - void res.status(400).send({ - ok: false, - title: 'Invalid input', - description: 'Failed to resolve SSO information due to invalid input.', - status: 400, - } satisfies Awaited>); - return; - } - - const result = await oidcIdLookup(inputResult.data.slug, storage, req.log); - - if (result.ok) { - void res.status(200).send(result); - return; - } - - void res.status(result.status).send(result); - return; - }); - createOtelAuthEndpoint({ server, authN, diff --git a/packages/services/server/src/use-sentry-user.ts b/packages/services/server/src/use-sentry-user.ts index 54eef97fbb1..1939002cdd4 100644 --- a/packages/services/server/src/use-sentry-user.ts +++ b/packages/services/server/src/use-sentry-user.ts @@ -1,10 +1,10 @@ import type { Plugin } from '@envelop/types'; import * as Sentry from '@sentry/node'; -export function extractUserId(context?: { user?: { superTokensUserId: string } }) { - const superTokensUserId = context?.user?.superTokensUserId; +export function extractUserId(context?: { user?: { betterAuthUserId: string } }) { + const betterAuthUserId = context?.user?.betterAuthUserId; - return superTokensUserId ?? null; + return betterAuthUserId ?? null; } export const useSentryUser = (): Plugin<{ diff --git a/packages/services/storage/schemats.cjs b/packages/services/storage/schemats.cjs index 51891dded23..f07de4aed44 100644 --- a/packages/services/storage/schemats.cjs +++ b/packages/services/storage/schemats.cjs @@ -5,5 +5,5 @@ module.exports = { conn: cn('registry'), // Prettier v3 is not supported here yet, but we don't really need it. prettier: false, - skipPrefix: ['supertokens_'], + skipPrefix: ['better_auth_'], }; diff --git a/packages/services/storage/src/db/types.ts b/packages/services/storage/src/db/types.ts index 2d563d08efd..cbcf0f00040 100644 --- a/packages/services/storage/src/db/types.ts +++ b/packages/services/storage/src/db/types.ts @@ -405,7 +405,7 @@ export interface users { id: string; is_admin: boolean | null; oidc_integration_id: string | null; - supertoken_user_id: string | null; + better_auth_user_id: string | null; zendesk_user_id: string | null; } diff --git a/packages/services/storage/src/index.ts b/packages/services/storage/src/index.ts index 517778c06bf..69231995f15 100644 --- a/packages/services/storage/src/index.ts +++ b/packages/services/storage/src/index.ts @@ -420,19 +420,19 @@ export async function createStorage( } const shared = { - async getUserBySuperTokenId( - { superTokensUserId }: { superTokensUserId: string }, + async getUserByBetterAuthId( + { betterAuthUserId }: { betterAuthUserId: string }, connection: Connection, ) { - const record = await connection.maybeOne(sql`/* getUserBySuperTokenId */ + const record = await connection.maybeOne(sql`/* getUserByBetterAuthId */ SELECT - ${userFields(sql`"users".`, sql`"stu".`)} + ${userFields(sql`"users".`, sql`"baa".`)} FROM "users" - LEFT JOIN "supertokens_thirdparty_users" AS "stu" - ON ("stu"."user_id" = "users"."supertoken_user_id") + LEFT JOIN "better_auth_accounts" AS "baa" + ON ("baa"."userId" = "users"."better_auth_user_id") WHERE - "users"."supertoken_user_id" = ${superTokensUserId} + "users"."better_auth_user_id" = ${betterAuthUserId} LIMIT 1 `); @@ -444,13 +444,13 @@ export async function createStorage( }, async createUser( { - superTokensUserId, + betterAuthUserId, email, fullName, displayName, oidcIntegrationId, }: { - superTokensUserId: string; + betterAuthUserId: string; email: string; fullName: string; displayName: string; @@ -461,13 +461,13 @@ export async function createStorage( await connection.query( sql`/* createUser */ INSERT INTO users - ("email", "supertoken_user_id", "full_name", "display_name", "oidc_integration_id") + ("email", "better_auth_user_id", "full_name", "display_name", "oidc_integration_id") VALUES - (${email}, ${superTokensUserId}, ${fullName}, ${displayName}, ${oidcIntegrationId}) + (${email}, ${betterAuthUserId}, ${fullName}, ${displayName}, ${oidcIntegrationId}) `, ); - const user = await this.getUserBySuperTokenId({ superTokensUserId }, connection); + const user = await this.getUserByBetterAuthId({ betterAuthUserId }, connection); if (!user) { throw new Error('Something went wrong.'); } @@ -549,7 +549,7 @@ export async function createStorage( }; function buildUserData(input: { - superTokensUserId: string; + betterAuthUserId: string; email: string; oidcIntegrationId: string | null; firstName: string | null; @@ -562,7 +562,7 @@ export async function createStorage( : input.email.split('@')[0].slice(0, 25).padEnd(2, '1'); return { - superTokensUserId: input.superTokensUserId, + betterAuthUserId: input.betterAuthUserId, email: input.email, displayName: name, fullName: name, @@ -583,13 +583,13 @@ export async function createStorage( } }, async ensureUserExists({ - superTokensUserId, + betterAuthUserId, email, oidcIntegration, firstName, lastName, }: { - superTokensUserId: string; + betterAuthUserId: string; firstName: string | null; lastName: string | null; email: string; @@ -599,12 +599,12 @@ export async function createStorage( }) { return tracedTransaction('ensureUserExists', pool, async t => { let action: 'created' | 'no_action' = 'no_action'; - let internalUser = await shared.getUserBySuperTokenId({ superTokensUserId }, t); + let internalUser = await shared.getUserByBetterAuthId({ betterAuthUserId }, t); if (!internalUser) { internalUser = await shared.createUser( buildUserData({ - superTokensUserId, + betterAuthUserId, email, oidcIntegrationId: oidcIntegration?.id ?? null, firstName, @@ -629,18 +629,18 @@ export async function createStorage( return action; }); }, - async getUserBySuperTokenId({ superTokensUserId }) { - return shared.getUserBySuperTokenId({ superTokensUserId }, pool); + async getUserByBetterAuthId({ betterAuthUserId }) { + return shared.getUserByBetterAuthId({ betterAuthUserId }, pool); }, getUserById: batch(async input => { const userIds = input.map(i => i.id); const records = await pool.any(sql`/* getUserById */ SELECT - ${userFields(sql`"users".`, sql`"stu".`)} + ${userFields(sql`"users".`, sql`"baa".`)} FROM "users" - LEFT JOIN "supertokens_thirdparty_users" AS "stu" - ON ("stu"."user_id" = "users"."supertoken_user_id") + LEFT JOIN "better_auth_accounts" AS "baa" + ON ("baa"."userId" = "users"."better_auth_user_id") WHERE "users"."id" = ANY(${sql.array(userIds, 'uuid')}) `); @@ -845,7 +845,7 @@ export async function createStorage( >( sql`/* getOrganizationOwner */ SELECT - ${userFields(sql`"u".`, sql`"stu".`)}, + ${userFields(sql`"u".`, sql`"baa".`)}, omr.scopes as scopes, om.organization_id, om.connected_to_zendesk, @@ -858,7 +858,7 @@ export async function createStorage( LEFT JOIN users as u ON (u.id = o.user_id) LEFT JOIN organization_member as om ON (om.user_id = u.id AND om.organization_id = o.id) LEFT JOIN organization_member_roles as omr ON (omr.organization_id = o.id AND omr.id = om.role_id) - LEFT JOIN supertokens_thirdparty_users as stu ON (stu.user_id = u.supertoken_user_id) + LEFT JOIN better_auth_accounts as baa ON (baa.userId = u.better_auth_user_id) WHERE o.id = ANY(${sql.array(organizations, 'uuid')})`, ); @@ -895,7 +895,7 @@ export async function createStorage( >( sql`/* getOrganizationMember */ SELECT - ${userFields(sql`"u".`, sql`"stu".`)}, + ${userFields(sql`"u".`, sql`"baa".`)}, omr.scopes as scopes, om.organization_id, om.connected_to_zendesk, @@ -909,7 +909,7 @@ export async function createStorage( LEFT JOIN organizations as o ON (o.id = om.organization_id) LEFT JOIN users as u ON (u.id = om.user_id) LEFT JOIN organization_member_roles as omr ON (omr.organization_id = o.id AND omr.id = om.role_id) - LEFT JOIN supertokens_thirdparty_users as stu ON (stu.user_id = u.supertoken_user_id) + LEFT JOIN better_auth_accounts as baa ON (baa.userId = u.better_auth_user_id) WHERE (om.organization_id, om.user_id) IN ((${sql.join( selectors.map(s => sql`${s.organizationId}, ${s.userId}`), sql`), (`, @@ -5292,18 +5292,18 @@ export type PaginatedOrganizationInvitationConnection = Readonly<{ export const userFields = ( user: TaggedTemplateLiteralInvocation, - superTokensThirdParty: TaggedTemplateLiteralInvocation, + betterAuthAccounts: TaggedTemplateLiteralInvocation, ) => sql` ${user}"id" , ${user}"email" , to_json(${user}"created_at") AS "createdAt" , ${user}"display_name" AS "displayName" , ${user}"full_name" AS "fullName" - , ${user}"supertoken_user_id" AS "superTokensUserId" + , ${user}"better_auth_user_id" AS "betterAuthUserId" , ${user}"is_admin" AS "isAdmin" , ${user}"oidc_integration_id" AS "oidcIntegrationId" , ${user}"zendesk_user_id" AS "zendeskId" - , ${superTokensThirdParty}"third_party_id" AS "provider" + , ${betterAuthAccounts}"providerId" AS "provider" `; export const UserModel = zod.object({ @@ -5312,7 +5312,7 @@ export const UserModel = zod.object({ createdAt: zod.string(), displayName: zod.string(), fullName: zod.string(), - superTokensUserId: zod.string(), + betterAuthUserId: zod.string(), isAdmin: zod .boolean() .nullable() diff --git a/packages/web/app/package.json b/packages/web/app/package.json index 015a11387ec..5b1a62fcde5 100644 --- a/packages/web/app/package.json +++ b/packages/web/app/package.json @@ -84,6 +84,7 @@ "@vitejs/plugin-react": "4.3.4", "@xyflow/react": "12.4.4", "autoprefixer": "10.4.21", + "better-auth": "^1.3.29", "class-variance-authority": "0.7.1", "clsx": "2.1.1", "cmdk": "0.2.1", diff --git a/packages/web/app/src/components/authenticated-container.tsx b/packages/web/app/src/components/authenticated-container.tsx index b457a4e7e9a..5e389fb21dd 100644 --- a/packages/web/app/src/components/authenticated-container.tsx +++ b/packages/web/app/src/components/authenticated-container.tsx @@ -1,6 +1,7 @@ import { ReactElement } from 'react'; -import { SessionAuth } from 'supertokens-auth-react/recipe/session'; +import { authClient } from '@/lib/auth'; import { HiveStripeWrapper } from '@/lib/billing/stripe'; +import { Navigate, useLocation } from '@tanstack/react-router'; /** * Utility for wrapping a component with an authenticated container that has the default application layout. @@ -8,11 +9,29 @@ import { HiveStripeWrapper } from '@/lib/billing/stripe'; export const authenticated = (Component: (props: TProps) => ReactElement | null) => (props: TProps) => { + const session = authClient.useSession(); + const location = useLocation(); + + if (session.isPending) { + return null; + } + + if (session.error) { + throw session.error; + } + + if (!session.data) { + return ( + + ); + } + return ( - - - - - + + + ); }; diff --git a/packages/web/app/src/components/error.tsx b/packages/web/app/src/components/error.tsx index e503574d1c9..379c3ea3917 100644 --- a/packages/web/app/src/components/error.tsx +++ b/packages/web/app/src/components/error.tsx @@ -1,20 +1,20 @@ import { useEffect } from 'react'; import { LogOutIcon } from 'lucide-react'; -import { useSessionContext } from 'supertokens-auth-react/recipe/session'; import { Button } from '@/components/ui/button'; +import { authClient } from '@/lib/auth'; import { captureException, flush } from '@sentry/react'; import { useRouter } from '@tanstack/react-router'; export function ErrorComponent(props: { error: any; message?: string }) { const router = useRouter(); - const session = useSessionContext(); + const session = authClient.useSession(); useEffect(() => { captureException(props.error); void flush(2000); }, []); - const isLoggedIn = !session.loading && session.doesSessionExist; + const isLoggedIn = !session.isPending && session.data != null; return (
diff --git a/packages/web/app/src/lib/auth.ts b/packages/web/app/src/lib/auth.ts new file mode 100644 index 00000000000..1992f42ce40 --- /dev/null +++ b/packages/web/app/src/lib/auth.ts @@ -0,0 +1,7 @@ +import { createAuthClient } from 'better-auth/react'; +import { env } from '@/env/frontend'; + +export const authClient = createAuthClient({ + baseURL: env.graphqlPublicOrigin, + basePath: '/auth-api', +}); diff --git a/packages/web/app/src/lib/supertokens/start-auth-flow-for-provider.ts b/packages/web/app/src/lib/supertokens/start-auth-flow-for-provider.ts index d1123ecb0eb..bf3cb95b717 100644 --- a/packages/web/app/src/lib/supertokens/start-auth-flow-for-provider.ts +++ b/packages/web/app/src/lib/supertokens/start-auth-flow-for-provider.ts @@ -1,5 +1,6 @@ import { getAuthorisationURLWithQueryParamsAndSetState } from 'supertokens-auth-react/recipe/thirdpartyemailpassword'; import { env } from '@/env/frontend'; +import { authClient } from '../auth'; import { updateLastAuthMethod } from './last-auth-method'; /** @@ -21,6 +22,10 @@ export const startAuthFlowForProvider = async ( redirectToPath && providersWithRedirectPartSupport.includes(thirdPartyId) ? `?redirectToPath=${encodeURIComponent(redirectToPath)}` : ''; + // const result = await authClient.signIn.social({ + // provider: thirdPartyId, + // callbackURL: `${env.appBaseUrl}/auth/callback/${thirdPartyId}${redirectPart}`, + // }); const authUrl = await getAuthorisationURLWithQueryParamsAndSetState({ thirdPartyId, frontendRedirectURI: `${env.appBaseUrl}/auth/callback/${thirdPartyId}${redirectPart}`, diff --git a/packages/web/app/src/pages/auth-sign-up.tsx b/packages/web/app/src/pages/auth-sign-up.tsx index 0c5c8f2ac6b..9d2088d462f 100644 --- a/packages/web/app/src/pages/auth-sign-up.tsx +++ b/packages/web/app/src/pages/auth-sign-up.tsx @@ -2,9 +2,6 @@ import { useCallback, useEffect } from 'react'; import { useForm } from 'react-hook-form'; import { FaRegUserCircle } from 'react-icons/fa'; import { SiGithub, SiGoogle, SiOkta } from 'react-icons/si'; -import { sendVerificationEmail } from 'supertokens-auth-react/recipe/emailverification'; -import { useSessionContext } from 'supertokens-auth-react/recipe/session'; -import { emailPasswordSignUp } from 'supertokens-auth-react/recipe/thirdpartyemailpassword'; import z from 'zod'; import { AuthCard, @@ -27,10 +24,11 @@ import { Meta } from '@/components/ui/meta'; import { TooltipProvider } from '@/components/ui/tooltip'; import { useToast } from '@/components/ui/use-toast'; import { env } from '@/env/frontend'; +import { authClient } from '@/lib/auth'; import { useLastAuthMethod } from '@/lib/supertokens/last-auth-method'; import { startAuthFlowForProvider } from '@/lib/supertokens/start-auth-flow-for-provider'; import { enabledProviders, isProviderEnabled } from '@/lib/supertokens/thirdparty'; -import { exhaustiveGuard } from '@/lib/utils'; +import { BASE_ERROR_CODES } from '@better-auth/core/error'; import { zodResolver } from '@hookform/resolvers/zod'; import { useMutation } from '@tanstack/react-query'; import { Link, Navigate, useRouter } from '@tanstack/react-router'; @@ -56,10 +54,10 @@ type SignUpFormValues = z.infer; export function AuthSignUpPage(props: { redirectToPath: string }) { const [lastAuthMethod] = useLastAuthMethod(); const router = useRouter(); - const session = useSessionContext(); + const session = authClient.useSession(); const sendVerificationEmailMutation = useMutation({ - mutationFn: () => sendVerificationEmail(), + mutationFn: (email: string) => authClient.sendVerificationEmail({ email }), onSuccess() { void router.navigate({ to: '/auth/verify-email', @@ -77,41 +75,46 @@ export function AuthSignUpPage(props: { redirectToPath: string }) { }); const signUp = useMutation({ - mutationFn: emailPasswordSignUp, - onSuccess(data) { - const status = data.status; + mutationFn: (params: { email: string; password: string; name: string }) => + authClient.signUp.email({ ...params }), + onSuccess({ data, error }) { + if (data?.user) { + if (env.auth.requireEmailVerification) { + sendVerificationEmailMutation.mutate(data.user.email); + } else { + void router.navigate({ + to: props.redirectToPath, + }); + } + } - switch (status) { - case 'OK': { - if (env.auth.requireEmailVerification) { - sendVerificationEmailMutation.mutate(); - } else { - void router.navigate({ - to: props.redirectToPath, - }); - } + switch (error?.message) { + case BASE_ERROR_CODES.INVALID_EMAIL: + form.setError('email', { + type: 'manual', + message: error.message, + }); break; - } - case 'FIELD_ERROR': { - for (const field of data.formFields) { - form.setError(field.id as keyof SignUpFormValues, { - type: 'manual', - message: field.error, - }); - } + case BASE_ERROR_CODES.PASSWORD_TOO_SHORT: + case BASE_ERROR_CODES.PASSWORD_TOO_LONG: + form.setError('password', { + type: 'manual', + message: error.message, + }); break; - } - case 'SIGN_UP_NOT_ALLOWED': { + case BASE_ERROR_CODES.USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL: toast({ - title: 'Sign up not allowed', - description: 'Please contact support for assistance.', + title: 'Email already in use', + description: 'Please use a different email address.', variant: 'destructive', }); break; - } - default: { - exhaustiveGuard(status); - } + default: + toast({ + title: 'Failed to sign up', + description: 'Please contact support for assistance.', + variant: 'destructive', + }); } }, onError(error) { @@ -161,35 +164,20 @@ export function AuthSignUpPage(props: { redirectToPath: string }) { (data: SignUpFormValues) => { signUp.reset(); signUp.mutate({ - formFields: [ - { - id: 'email', - value: data.email, - }, - { - id: 'password', - value: data.password, - }, - { - id: 'firstName', - value: data.firstName, - }, - { - id: 'lastName', - value: data.lastName, - }, - ], + email: data.email, + password: data.password, + name: `${data.firstName} ${data.lastName}`, }); }, [signUp.mutate], ); - if (session.loading) { + if (session.isPending) { // AuthPage component already shows a loading state return null; } - if (session.doesSessionExist) { + if (session.data) { // Redirect to the home page if the user is already signed in return ; } @@ -270,7 +258,7 @@ export function AuthSignUpPage(props: { redirectToPath: string }) { )} /> @@ -63,7 +53,7 @@ function AuthVerifyEmail() { ); } - if (emailVerification.isPending) { + if (sendVerificationEmailMutation.status !== 'idle') { return ( - - - -

There was an unexpected error when verifying your email address.

- - -
-
-
- ); - } - - if (emailVerification.isSuccess && emailVerification.data.status === 'OK') { + if (user.emailVerified) { return ( - - - -

The email verification link has expired.

- -
-
-
- ); - } - return ( @@ -155,7 +101,7 @@ function AuthVerifyEmail() { diff --git a/packages/web/app/src/pages/auth.tsx b/packages/web/app/src/pages/auth.tsx index 6eb9002b0ff..a28eb913751 100644 --- a/packages/web/app/src/pages/auth.tsx +++ b/packages/web/app/src/pages/auth.tsx @@ -1,8 +1,8 @@ import { BookIcon } from 'lucide-react'; import { SiGithub } from 'react-icons/si'; -import { useSessionContext } from 'supertokens-auth-react/recipe/session'; import { HiveLogo } from '@/components/ui/icon'; import { Meta } from '@/components/ui/meta'; +import { authClient } from '@/lib/auth'; import { Link, Outlet } from '@tanstack/react-router'; function ExternalLink(props: { href: string; children: React.ReactNode }) { @@ -18,56 +18,57 @@ function ExternalLink(props: { href: string; children: React.ReactNode }) { } export function AuthPage() { - const session = useSessionContext(); + const session = authClient.useSession(); + + if (session.error) { + throw session.error; + } return ( <>
- <> - {session.loading ? ( -
- -
- ) : ( -
-
-
- -
- - GraphQL Hive -
- -
-
-

- Open-source GraphQL management - platform -

-

- Prevent breaking changes, monitor performance of your GraphQL API, and manage - your API gateway -

-
- - - Documentation - - - - Github - -
+ {session.isPending ? ( +
+ +
+ ) : ( +
+
+
+ +
+ + GraphQL Hive +
+ +
+
+

+ Open-source GraphQL management platform +

+

+ Prevent breaking changes, monitor performance of your GraphQL API, and manage + your API gateway +

+
+ + + Documentation + + + + Github +
-
- -
- )} - +
+ +
+
+ )}
); diff --git a/packages/web/app/src/pages/logout.ts b/packages/web/app/src/pages/logout.ts index 0df847554e2..e9dae215ba6 100644 --- a/packages/web/app/src/pages/logout.ts +++ b/packages/web/app/src/pages/logout.ts @@ -1,15 +1,22 @@ import { useEffect } from 'react'; -import { signOut } from 'supertokens-auth-react/recipe/thirdpartyemailpassword'; +import { authClient } from '@/lib/auth'; +import { captureException } from '@sentry/react'; import { useRouter } from '@tanstack/react-router'; export function LogoutPage() { const router = useRouter(); useEffect(() => { - void signOut().then(() => { - void router.navigate({ - to: '/', + void authClient + .signOut() + .then(() => { + void router.navigate({ + to: '/', + }); + }) + .catch(error => { + console.error(error); + captureException(error); }); - }); }); return null; diff --git a/packages/web/app/src/pages/organization-join.tsx b/packages/web/app/src/pages/organization-join.tsx index 6a122e980ed..5518dcaca2c 100644 --- a/packages/web/app/src/pages/organization-join.tsx +++ b/packages/web/app/src/pages/organization-join.tsx @@ -1,6 +1,5 @@ import { useCallback } from 'react'; import { LogOutIcon } from 'lucide-react'; -import { SessionAuth, useSessionContext } from 'supertokens-auth-react/recipe/session'; import { useMutation, useQuery } from 'urql'; import { Button } from '@/components/ui/button'; import { Card, CardContent, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'; @@ -11,6 +10,7 @@ import { Spinner } from '@/components/ui/spinner'; import { useToast } from '@/components/ui/use-toast'; import { DataWrapper } from '@/components/v2/data-wrapper'; import { graphql } from '@/gql'; +import { authClient } from '@/lib/auth'; import { HiveStripeWrapper } from '@/lib/billing/stripe'; import { Link, useRouter } from '@tanstack/react-router'; @@ -50,7 +50,7 @@ const JoinOrganizationPage_OrganizationInvitationQuery = graphql(` export function JoinOrganizationPage(props: { inviteCode: string }) { const router = useRouter(); - const session = useSessionContext(); + const session = authClient.useSession(); const { toast } = useToast(); const code = props.inviteCode; const [query] = useQuery({ @@ -92,11 +92,11 @@ export function JoinOrganizationPage(props: { inviteCode: string }) { ? query.data.organizationByInviteCode.name : null; - if (session.loading) { + if (session.isPending) { return ; } - if (!session.loading && !session.doesSessionExist) { + if (!session.isPending && !session.data) { toast({ title: 'Account Required', description: @@ -114,87 +114,85 @@ export function JoinOrganizationPage(props: { inviteCode: string }) { } return ( - - - - - - - - -
- - {({ data }) => { - if (data.organizationByInviteCode == null) { - return null; - } - const invitation = data.organizationByInviteCode; - - if (invitation.__typename === 'OrganizationInvitationError') { - return ( -
- - - Invitation Error - - {invitation.message} - - - - -
- ); - } + + + + + + + +
+ + {({ data }) => { + if (data.organizationByInviteCode == null) { + return null; + } + const invitation = data.organizationByInviteCode; + if (invitation.__typename === 'OrganizationInvitationError') { return (
- Join "{invitation.name}" organization + Invitation Error - -

- You've been invited to become a member of{' '} - {invitation.name}. -

-

- By accepting the invitation, you will be able to collaborate with other - members of this organization. -

-
- - -
); - }} -
-
-
-
- + } + + return ( +
+ + + Join "{invitation.name}" organization + + +

+ You've been invited to become a member of{' '} + {invitation.name}. +

+

+ By accepting the invitation, you will be able to collaborate with other + members of this organization. +

+
+ + + + +
+
+ ); + }} +
+
+
+
); } diff --git a/packages/web/app/src/router.tsx b/packages/web/app/src/router.tsx index 28c00627a57..1702999c0d0 100644 --- a/packages/web/app/src/router.tsx +++ b/packages/web/app/src/router.tsx @@ -2,13 +2,10 @@ import { lazy, useCallback, useEffect, useMemo } from 'react'; import { parse as jsUrlParse, stringify as jsUrlStringify } from 'jsurl2'; import { Helmet, HelmetProvider } from 'react-helmet-async'; import { ToastContainer } from 'react-toastify'; -import SuperTokens, { SuperTokensWrapper } from 'supertokens-auth-react'; -import Session from 'supertokens-auth-react/recipe/session'; import { Provider as UrqlProvider } from 'urql'; import { z } from 'zod'; import { LoadingAPIIndicator } from '@/components/common/LoadingAPI'; import { Toaster } from '@/components/ui/toaster'; -import { frontendConfig } from '@/config/supertokens/frontend'; import { env } from '@/env/frontend'; import * as gtag from '@/lib/gtag'; import { urqlClient } from '@/lib/urql'; @@ -29,6 +26,7 @@ import { NotFound } from './components/not-found'; import 'react-toastify/dist/ReactToastify.css'; import { zodValidator } from '@tanstack/zod-adapter'; import { authenticated } from './components/authenticated-container'; +import { authClient } from './lib/auth'; import { AuthPage } from './pages/auth'; import { AuthCallbackPage } from './pages/auth-callback'; import { AuthOIDCPage } from './pages/auth-oidc'; @@ -83,7 +81,6 @@ import { TargetTracesSort, } from './pages/target-traces'; -SuperTokens.init(frontendConfig()); if (env.sentry) { init({ dsn: env.sentry.dsn, @@ -110,12 +107,11 @@ function identifyOnSentry(userId: string, email: string): void { function RootComponent() { useEffect(() => { - void Session.doesSessionExist().then(async doesExist => { - if (!doesExist) { + void authClient.getSession().then(async session => { + if (!session.data) { return; } - const payload = await Session.getAccessTokenPayloadSecurely(); - identifyOnSentry(payload.superTokensUserId, payload.email); + identifyOnSentry(session.data.user.id, session.data.user.email); }); }, []); @@ -140,14 +136,12 @@ function RootComponent() { )} - - - - - - - - + + + + + + {/* eslint-disable-next-line no-process-env */} {process.env.NODE_ENV === 'development' && } diff --git a/patches/@better-auth__core.patch b/patches/@better-auth__core.patch new file mode 100644 index 00000000000..d65ba7b28d4 --- /dev/null +++ b/patches/@better-auth__core.patch @@ -0,0 +1,58 @@ +diff --git a/package.json b/package.json +index 23ae9e5f5f48702456e7c4d737f672422a8c9980..5662e6bf77d032709d50f7d3e68a45af47fa5d19 100644 +--- a/package.json ++++ b/package.json +@@ -109,35 +109,38 @@ + }, + "typesVersions": { + "*": { +- "index": [ ++ ".": [ + "dist/index.d.ts" + ], + "async_hooks": [ +- "dist/async_hooks.d.ts" ++ "dist/async_hooks/index.d.ts" + ], +- "db": [ +- "dist/db.d.ts" +- ], +- "db/adapter": [ +- "dist/db/adapter/index.d.ts" ++ "context": [ ++ "dist/context/index.d.ts" + ], + "env": [ +- "dist/env.d.ts" ++ "dist/env/index.d.ts" + ], + "error": [ +- "dist/error.d.ts" ++ "dist/error/index.d.ts" + ], + "middleware": [ +- "dist/middleware.d.ts" ++ "dist/middleware/index.d.ts" + ], +- "oauth2": [ +- "dist/oauth2.d.ts" ++ "utils": [ ++ "dist/utils/index.d.ts" + ], + "social-providers": [ +- "dist/social-providers.d.ts" ++ "dist/social-providers/index.d.ts" + ], +- "utils": [ +- "dist/utils.d.ts" ++ "db": [ ++ "dist/db/index.d.ts" ++ ], ++ "db/adapter": [ ++ "dist/db/adapter/index.d.ts" ++ ], ++ "oauth2": [ ++ "dist/oauth2/index.d.ts" + ] + } + }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a20aa99c9e5..bb8d1f7f4f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,6 +21,9 @@ patchedDependencies: '@apollo/federation@0.38.1': hash: cb592719b35ac58f48c97dd557e19223b45b2c5544bec4f6f2e741c58b7f1de9 path: patches/@apollo__federation@0.38.1.patch + '@better-auth/core': + hash: 8ab0ea888a8dd5e27ac74f518933c4deeb1815d41f31174635103c32ec5df160 + path: patches/@better-auth__core.patch '@fastify/vite': hash: f5ce073a4db250ed3db1d9c19e2a253418454ee379530bdee25869570d7b500b path: patches/@fastify__vite.patch @@ -220,10 +223,10 @@ importers: version: 5.7.3 vite-tsconfig-paths: specifier: 5.1.4 - version: 5.1.4(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) + version: 5.1.4(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) vitest: specifier: 3.2.4 - version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) deployment: dependencies: @@ -374,7 +377,7 @@ importers: version: 2.8.1 vitest: specifier: 3.2.4 - version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) zod: specifier: 3.25.76 version: 3.25.76 @@ -420,7 +423,7 @@ importers: version: 14.0.10 vitest: specifier: 3.2.4 - version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) ws: specifier: '>=8.18.0 || >=7.5.10 || >=6.2.3 || >=5.2.4' version: 8.18.0 @@ -549,7 +552,7 @@ importers: version: 2.8.1 vitest: specifier: 3.2.4 - version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) publishDirectory: dist packages/libraries/envelop: @@ -597,41 +600,41 @@ importers: version: link:../core/dist '@graphql-yoga/plugin-persisted-operations': specifier: ^3.9.0 - version: 3.9.0(@graphql-tools/utils@10.9.1(graphql@16.9.0))(graphql-yoga@5.13.3(graphql@16.9.0))(graphql@16.9.0) + version: 3.9.0(@graphql-tools/utils@10.9.1(graphql@16.11.0))(graphql-yoga@5.13.3(graphql@16.11.0))(graphql@16.11.0) graphql: specifier: ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - version: 16.9.0 + version: 16.11.0 devDependencies: '@graphql-tools/schema': specifier: 10.0.25 - version: 10.0.25(graphql@16.9.0) + version: 10.0.25(graphql@16.11.0) '@graphql-yoga/plugin-defer-stream': specifier: 3.7.0 - version: 3.7.0(graphql-yoga@5.13.3(graphql@16.9.0))(graphql@16.9.0) + version: 3.7.0(graphql-yoga@5.13.3(graphql@16.11.0))(graphql@16.11.0) '@graphql-yoga/plugin-disable-introspection': specifier: 2.7.0 - version: 2.7.0(graphql-yoga@5.13.3(graphql@16.9.0))(graphql@16.9.0) + version: 2.7.0(graphql-yoga@5.13.3(graphql@16.11.0))(graphql@16.11.0) '@graphql-yoga/plugin-graphql-sse': specifier: 3.7.0 - version: 3.7.0(graphql-yoga@5.13.3(graphql@16.9.0))(graphql@16.9.0) + version: 3.7.0(graphql-yoga@5.13.3(graphql@16.11.0))(graphql@16.11.0) '@graphql-yoga/plugin-response-cache': specifier: 3.9.0 - version: 3.9.0(@envelop/core@5.3.1)(graphql-yoga@5.13.3(graphql@16.9.0))(graphql@16.9.0) + version: 3.9.0(@envelop/core@5.3.1)(graphql-yoga@5.13.3(graphql@16.11.0))(graphql@16.11.0) '@whatwg-node/fetch': specifier: 0.10.6 version: 0.10.6 graphql-ws: specifier: 5.16.1 - version: 5.16.1(graphql@16.9.0) + version: 5.16.1(graphql@16.11.0) graphql-yoga: specifier: 5.13.3 - version: 5.13.3(graphql@16.9.0) + version: 5.13.3(graphql@16.11.0) nock: specifier: 14.0.10 version: 14.0.10 vitest: specifier: 3.2.4 - version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) ws: specifier: '>=8.18.0 || >=7.5.10 || >=6.2.3 || >=5.2.4' version: 8.18.0 @@ -888,7 +891,7 @@ importers: version: 6.21.3 vitest: specifier: 3.2.4 - version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) zod: specifier: 3.25.76 version: 3.25.76 @@ -921,7 +924,7 @@ importers: version: 6.21.3 vitest: specifier: 3.2.4 - version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + version: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) workers-loki-logger: specifier: 0.1.15 version: 0.1.15 @@ -1232,6 +1235,9 @@ importers: packages/services/server: devDependencies: + '@better-auth/sso': + specifier: ^1.3.27 + version: 1.3.27(better-auth@1.3.29) '@envelop/core': specifier: 5.0.2 version: 5.0.2 @@ -1313,9 +1319,18 @@ importers: '@trpc/server': specifier: 10.45.2 version: 10.45.2 + '@types/bcrypt': + specifier: ^6.0.0 + version: 6.0.0 '@whatwg-node/server': specifier: 0.10.5 version: 0.10.5 + bcrypt: + specifier: ^6.0.0 + version: 6.0.0 + better-auth: + specifier: ^1.3.29 + version: 1.3.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) dotenv: specifier: 16.4.7 version: 16.4.7 @@ -1337,6 +1352,9 @@ importers: ioredis: specifier: 5.4.2 version: 5.4.2 + pg: + specifier: 8.13.1 + version: 8.13.1 pino-pretty: specifier: 11.3.0 version: 11.3.0 @@ -1829,7 +1847,7 @@ importers: version: 8.4.7(@storybook/test@8.4.7(storybook@8.4.7(prettier@3.4.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7(prettier@3.4.2))(typescript@5.7.3) '@storybook/react-vite': specifier: 8.4.7 - version: 8.4.7(@storybook/test@8.4.7(storybook@8.4.7(prettier@3.4.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7(prettier@3.4.2))(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) + version: 8.4.7(@storybook/test@8.4.7(storybook@8.4.7(prettier@3.4.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7(prettier@3.4.2))(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) '@stripe/react-stripe-js': specifier: 3.1.1 version: 3.1.1(@stripe/stripe-js@5.5.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -1898,13 +1916,16 @@ importers: version: 7.1.0(@urql/core@5.0.3(graphql@16.9.0))(graphql@16.9.0) '@vitejs/plugin-react': specifier: 4.3.4 - version: 4.3.4(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) + version: 4.3.4(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) '@xyflow/react': specifier: 12.4.4 version: 12.4.4(@types/react@18.3.18)(immer@10.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) autoprefixer: specifier: 10.4.21 version: 10.4.21(postcss@8.5.6) + better-auth: + specifier: ^1.3.29 + version: 1.3.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) class-variance-authority: specifier: 0.7.1 version: 0.7.1 @@ -2078,10 +2099,10 @@ importers: version: 1.13.2(@types/react@18.3.18)(react@18.3.1) vite: specifier: 7.1.5 - version: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + version: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) vite-tsconfig-paths: specifier: 5.1.4 - version: 5.1.4(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) + version: 5.1.4(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) wonka: specifier: 6.3.4 version: 6.3.4 @@ -2470,6 +2491,10 @@ packages: '@apollo/server': ^4.0.0 || ^5.0.0 express: ^4.0.0 + '@authenio/xml-encryption@2.0.2': + resolution: {integrity: sha512-cTlrKttbrRHEw3W+0/I609A2Matj5JQaRvfLtEIGZvlN0RaPi+3ANsMeqAyCAVlH/lUIW2tmtBlSMni74lcXeg==} + engines: {node: '>=12'} + '@aws-crypto/crc32@5.2.0': resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} engines: {node: '>=16.0.0'} @@ -3076,6 +3101,30 @@ packages: bentocache: ^1.0.0 prom-client: ^15.0.0 + '@better-auth/core@1.3.29': + resolution: {integrity: sha512-Ka2mg4qZACFaLY7DOGFXv1Ma8CkF17k0ClUd2U/ZJbbSoEPI5gnVguEmakJB6HFYswszeZh2295IFORtW9wf7A==} + peerDependencies: + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.18 + better-call: 1.0.19 + jose: ^6.1.0 + kysely: ^0.28.5 + nanostores: ^1.0.1 + + '@better-auth/sso@1.3.27': + resolution: {integrity: sha512-a/dnm3kQS58H69XYZCD0yp0Zo7G5ndMPBH9AbLl9uaodPJ2qqtmIWjZcT0/5EtRp8VGLucK6ajxNUlIzYrgLZQ==} + peerDependencies: + better-auth: 1.3.27 + + '@better-auth/telemetry@1.3.29': + resolution: {integrity: sha512-1BFh3YulYDrwWcUkfEWddcrcApACyI4wtrgq3NBd9y+tilBRjWTCWEPuRqJrfM3a5F1ZSqsvOYfFG1XZbkxlVw==} + + '@better-auth/utils@0.3.0': + resolution: {integrity: sha512-W+Adw6ZA6mgvnSnhOki270rwJ42t4XzSK6YWGF//BbVXL6SwCLWfyzBc1lN2m/4RM28KubdBKQ4X5VMoLRNPQw==} + + '@better-fetch/fetch@1.1.18': + resolution: {integrity: sha512-rEFOE1MYIsBmoMJtQbl32PGHHXuG2hDxvEd7rUHE0vCBoFQVSDqaVs9hkZEtHCxRoY+CljXKFCOuJ8uxqw1LcA==} + '@boringnode/bus@0.7.0': resolution: {integrity: sha512-bOL0B22ukDG2wkd8WGGhTHp2I3YhcaphFXvt8oFwJ8/T+ERVECTG6WJBgH0h4B5l/8pKjbjNxmhIXniQ5RwI8g==} engines: {node: '>=20.11.1'} @@ -3204,11 +3253,11 @@ packages: '@codemirror/language@6.10.2': resolution: {integrity: sha512-kgbTYTo0Au6dCSc/TFy7fK3fpJmgHDv1sG1KNQKJXVi+xBTEeBPY/M30YXiU6mMXeH+YIDLsbrT4ZwNRdtF+SA==} - '@codemirror/state@6.5.0': - resolution: {integrity: sha512-MwBHVK60IiIHDcoMet78lxt6iw5gJOGSbNbOIVBHWVXIH4/Nq1+GQgLLGgI1KlnN86WDXsPudVaqYHKBIx7Eyw==} + '@codemirror/state@6.5.2': + resolution: {integrity: sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==} - '@codemirror/view@6.36.1': - resolution: {integrity: sha512-miD1nyT4m4uopZaDdO2uXU/LLHliKNYL9kB1C1wJHrunHLm/rpkb5QVSokqgw9hFqEZakrdlb/VGWX8aYZTslQ==} + '@codemirror/view@6.38.6': + resolution: {integrity: sha512-qiS0z1bKs5WOvHIAC0Cybmv4AJSkAXgX5aD6Mqd2epSLlVJsQl8NG23jCVouIgkh4All/mrbdsf2UOLFnJw0tw==} '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} @@ -4478,6 +4527,9 @@ packages: react: ^18 || ^19 || ^19.0.0-rc react-dom: ^18 || ^19 || ^19.0.0-rc + '@hexagon/base64@1.1.28': + resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} + '@hookform/resolvers@3.10.0': resolution: {integrity: sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag==} peerDependencies: @@ -4820,6 +4872,9 @@ packages: typescript: optional: true + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/gen-mapping@0.3.8': resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} engines: {node: '>=6.0.0'} @@ -4828,12 +4883,16 @@ packages: resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} engines: {node: '>=6.0.0'} + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + '@jridgewell/set-array@1.2.1': resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} - '@jridgewell/source-map@0.3.6': - resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} '@jridgewell/sourcemap-codec@1.4.15': resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} @@ -4841,9 +4900,15 @@ packages: '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} @@ -4862,11 +4927,14 @@ packages: '@lbrlabs/pulumi-grafana@0.1.0': resolution: {integrity: sha512-REc/LQOy17O9jbZnBNm4tLjLJKxOfLaWPIB2CFiAtM1VzwU3FzZQFs0K+XGkuZwWdB+tl2/VHdHv+FqsUrit2w==} - '@lezer/common@1.2.3': - resolution: {integrity: sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA==} + '@levischuck/tiny-cbor@0.2.11': + resolution: {integrity: sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==} - '@lezer/highlight@1.2.1': - resolution: {integrity: sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA==} + '@lezer/common@1.3.0': + resolution: {integrity: sha512-L9X8uHCYU310o99L3/MpJKYxPzXPOS7S0NmBaM7UO/x2Kb2WbmMLSkfvdr1KxRIFYOpbY0Jhn7CfLSUDzL8arQ==} + + '@lezer/highlight@1.2.2': + resolution: {integrity: sha512-z8TQwaBXXQIvG6i2g3e9cgMwUUXu9Ib7jo2qRRggdhwKpM56Dw3PM3wmexn+EGaaOZ7az0K7sjc3/gcGW7sz7A==} '@lezer/lr@1.4.2': resolution: {integrity: sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA==} @@ -5134,10 +5202,18 @@ packages: cpu: [x64] os: [win32] + '@noble/ciphers@2.0.1': + resolution: {integrity: sha512-xHK3XHPUW8DTAobU+G0XT+/w+JLM7/8k1UFdB5xg/zTFPnFCobhftzw8wl4Lw2aq/Rvir5pxfZV5fEazmeCJ2g==} + engines: {node: '>= 20.19.0'} + '@noble/hashes@1.7.1': resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} engines: {node: ^14.21.3 || >=16} + '@noble/hashes@2.0.1': + resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==} + engines: {node: '>= 20.19.0'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -6094,8 +6170,38 @@ packages: resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} - '@peculiar/asn1-schema@2.3.0': - resolution: {integrity: sha512-DtNLAG4vmDrdSJFPe7rypkcj597chNQL7u+2dBtYo5mh7VW2+im6ke+O0NVr8W1f4re4C3F71LhoMb0Yxqa48Q==} + '@peculiar/asn1-android@2.5.0': + resolution: {integrity: sha512-t8A83hgghWQkcneRsgGs2ebAlRe54ns88p7ouv8PW2tzF1nAW4yHcL4uZKrFpIU+uszIRzTkcCuie37gpkId0A==} + + '@peculiar/asn1-cms@2.5.0': + resolution: {integrity: sha512-p0SjJ3TuuleIvjPM4aYfvYw8Fk1Hn/zAVyPJZTtZ2eE9/MIer6/18ROxX6N/e6edVSfvuZBqhxAj3YgsmSjQ/A==} + + '@peculiar/asn1-csr@2.5.0': + resolution: {integrity: sha512-ioigvA6WSYN9h/YssMmmoIwgl3RvZlAYx4A/9jD2qaqXZwGcNlAxaw54eSx2QG1Yu7YyBC5Rku3nNoHrQ16YsQ==} + + '@peculiar/asn1-ecc@2.5.0': + resolution: {integrity: sha512-t4eYGNhXtLRxaP50h3sfO6aJebUCDGQACoeexcelL4roMFRRVgB20yBIu2LxsPh/tdW9I282gNgMOyg3ywg/mg==} + + '@peculiar/asn1-pfx@2.5.0': + resolution: {integrity: sha512-Vj0d0wxJZA+Ztqfb7W+/iu8Uasw6hhKtCdLKXLG/P3kEPIQpqGI4P4YXlROfl7gOCqFIbgsj1HzFIFwQ5s20ug==} + + '@peculiar/asn1-pkcs8@2.5.0': + resolution: {integrity: sha512-L7599HTI2SLlitlpEP8oAPaJgYssByI4eCwQq2C9eC90otFpm8MRn66PpbKviweAlhinWQ3ZjDD2KIVtx7PaVw==} + + '@peculiar/asn1-pkcs9@2.5.0': + resolution: {integrity: sha512-UgqSMBLNLR5TzEZ5ZzxR45Nk6VJrammxd60WMSkofyNzd3DQLSNycGWSK5Xg3UTYbXcDFyG8pA/7/y/ztVCa6A==} + + '@peculiar/asn1-rsa@2.5.0': + resolution: {integrity: sha512-qMZ/vweiTHy9syrkkqWFvbT3eLoedvamcUdnnvwyyUNv5FgFXA3KP8td+ATibnlZ0EANW5PYRm8E6MJzEB/72Q==} + + '@peculiar/asn1-schema@2.5.0': + resolution: {integrity: sha512-YM/nFfskFJSlHqv59ed6dZlLZqtZQwjRVJ4bBAiWV08Oc+1rSd5lDZcBEx0lGDHfSoH3UziI2pXt2UM33KerPQ==} + + '@peculiar/asn1-x509-attr@2.5.0': + resolution: {integrity: sha512-9f0hPOxiJDoG/bfNLAFven+Bd4gwz/VzrCIIWc1025LEI4BXO0U5fOCTNDPbbp2ll+UzqKsZ3g61mpBp74gk9A==} + + '@peculiar/asn1-x509@2.5.0': + resolution: {integrity: sha512-CpwtMCTJvfvYTFMuiME5IH+8qmDe3yEWzKHe7OOADbGfq7ohxeLaXwQo0q4du3qs0AII3UbLCvb9NF/6q0oTKQ==} '@peculiar/json-schema@1.1.12': resolution: {integrity: sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==} @@ -6105,6 +6211,9 @@ packages: resolution: {integrity: sha512-U58N44b2m3OuTgpmKgf0LPDOmP3bhwNz01vAnj1mBwxBASRhptWYK+M3zG+HBkDqGQM+bFsoIihTW8MdmPXEqg==} engines: {node: '>=10.12.0'} + '@peculiar/x509@1.14.0': + resolution: {integrity: sha512-Yc4PDxN3OrxUPiXgU63c+ZRXKGE8YKF2McTciYhUHFtHVB0KMnjeFSU0qpztGhsp4P0uKix4+J2xEpIEDu8oXg==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -7431,6 +7540,13 @@ packages: resolution: {integrity: sha512-1fTqnqyTBWvV7cftUUFtDcHPdSox0N3Ub7C0lRyReYx4zZUlNTZjCV+HPy4Lre+r45dV7Qx5JLKvqqsgxuyYfg==} engines: {node: ^16.14.0 || >=18.0.0} + '@simplewebauthn/browser@13.2.2': + resolution: {integrity: sha512-FNW1oLQpTJyqG5kkDg5ZsotvWgmBaC6jCHR7Ej0qUNep36Wl9tj2eZu7J5rP+uhXgHaLk+QQ3lqcw2vS5MX1IA==} + + '@simplewebauthn/server@13.2.2': + resolution: {integrity: sha512-HcWLW28yTMGXpwE9VLx9J+N2KEUaELadLrkPEEI9tpI5la70xNEVEsu/C+m3u7uoq4FulLqZQhgBCzR9IZhFpA==} + engines: {node: '>=20.0.0'} + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -8318,6 +8434,9 @@ packages: '@types/babel__traverse@7.18.3': resolution: {integrity: sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==} + '@types/bcrypt@6.0.0': + resolution: {integrity: sha512-/oJGukuH3D2+D+3H4JWLaAsJ/ji86dhRidzZ/Od7H/i8g+aCmvkeCc6Ni/f9uxGLSQVCRZkX2/lqEFG2BvWtlQ==} + '@types/bcryptjs@2.4.6': resolution: {integrity: sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==} @@ -8950,6 +9069,14 @@ packages: resolution: {integrity: sha512-CnYTFEUJkbbAcuBXnXirVIgKBfs2YA6sSGjxeq07AUiyXuoQ0fbvTIQoteMglmn09QeGzcH/l0B7nIml83xvVw==} engines: {node: '>=18.0.0'} + '@xmldom/is-dom-node@1.0.1': + resolution: {integrity: sha512-CJDxIgE5I0FH+ttq/Fxy6nRpxP70+e2O048EPe85J2use3XKdatVM7dDVvFNjQudd9B49NPoZ+8PG49zj4Er8Q==} + engines: {node: '>= 16'} + + '@xmldom/xmldom@0.8.11': + resolution: {integrity: sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==} + engines: {node: '>=10.0.0'} + '@xmldom/xmldom@0.9.8': resolution: {integrity: sha512-p96FSY54r+WJ50FIOsCOjyj/wavs8921hG5+kVMmZgKcvIKxMXHTrjNJvRgWa/zuX3B6t2lijLNFaOyuxUH+2A==} engines: {node: '>=14.6'} @@ -9006,6 +9133,11 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + addressparser@1.0.1: resolution: {integrity: sha512-aQX7AISOMM7HFE0iZ3+YnD07oIeJqWGVnJ+ZIKaBZAk03ftmVYVqsGas/rbXKR21n4D/hKCSHypvcyOkds/xzg==} @@ -9186,8 +9318,8 @@ packages: asn1@0.2.6: resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - asn1js@3.0.5: - resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} + asn1js@3.0.6: + resolution: {integrity: sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA==} engines: {node: '>=12.0.0'} assert-options@0.8.2: @@ -9295,13 +9427,25 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.8.19: + resolution: {integrity: sha512-zoKGUdu6vb2jd3YOq0nnhEDQVbPcHhco3UImJrv5dSkvxTc2pl2WjOPsjZXDwPDSl5eghIMuY3R6J9NDKF3KcQ==} + hasBin: true + baseline-browser-mapping@2.8.3: resolution: {integrity: sha512-mcE+Wr2CAhHNWxXN/DdTI+n4gsPc5QpXpWnyCQWiQYIYZX+ZMJ8juXZgjRa/0/YPJo/NSsgW15/YgmI4nbysYw==} hasBin: true + basic-auth@2.0.1: + resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} + engines: {node: '>= 0.8'} + bcrypt-pbkdf@1.0.2: resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + bcrypt@6.0.0: + resolution: {integrity: sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg==} + engines: {node: '>= 18'} + bcryptjs@2.4.3: resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} @@ -9328,6 +9472,38 @@ packages: orchid-orm: optional: true + better-auth@1.3.29: + resolution: {integrity: sha512-1va1XZLTQme3DX33PgHqwwVyOJya5H0+ozT6BhOjTnwecC50I75F0OqqTwINq4XZ0+GuD3bl3I55RiFP49jStw==} + peerDependencies: + '@lynx-js/react': '*' + '@sveltejs/kit': '*' + next: '*' + react: '*' + react-dom: '*' + solid-js: '*' + svelte: '*' + vue: '*' + peerDependenciesMeta: + '@lynx-js/react': + optional: true + '@sveltejs/kit': + optional: true + next: + optional: true + react: + optional: true + react-dom: + optional: true + solid-js: + optional: true + svelte: + optional: true + vue: + optional: true + + better-call@1.0.19: + resolution: {integrity: sha512-sI3GcA1SCVa3H+CDHl8W8qzhlrckwXOTKhqq3OOPXjgn5aTOMIqGY34zLY/pHA6tRRMjTUC3lz5Mi7EbDA24Kw==} + better-opn@3.0.2: resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} engines: {node: '>=12.0.0'} @@ -9424,6 +9600,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.27.0: + resolution: {integrity: sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} @@ -9545,9 +9726,16 @@ packages: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + caniuse-lite@1.0.30001741: resolution: {integrity: sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==} + caniuse-lite@1.0.30001751: + resolution: {integrity: sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==} + capital-case@1.0.4: resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} @@ -9977,6 +10165,9 @@ packages: create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + crelt@1.0.6: + resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + cron-parser@4.9.0: resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} engines: {node: '>=12.0.0'} @@ -10420,6 +10611,10 @@ packages: resolution: {integrity: sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==} engines: {node: '>=8'} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + detect-newline@4.0.1: resolution: {integrity: sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -10575,6 +10770,9 @@ packages: electron-to-chromium@1.5.218: resolution: {integrity: sha512-uwwdN0TUHs8u6iRgN8vKeWZMRll4gBkz+QMqdS7DDe49uiK68/UX92lFb61oiFPrpYZNeZIqa4bA7O6Aiasnzg==} + electron-to-chromium@1.5.239: + resolution: {integrity: sha512-1y5w0Zsq39MSPmEjHjbizvhYoTaulVtivpxkp5q5kaPmQtsK6/2nvAzGRxNMS9DoYySp9PkW0MAQDwU1m764mg==} + emoji-regex-xs@1.0.0: resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} @@ -11092,6 +11290,10 @@ packages: resolution: {integrity: sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==} hasBin: true + fast-xml-parser@5.3.0: + resolution: {integrity: sha512-gkWGshjYcQCF+6qtlrqBqELqNqnt4CxruY6UVAWWnqb3DQ6qaNFEIKqzYep1XzHLM/QtrHVCxyPOtTk4LTQ7Aw==} + hasBin: true + fastest-levenshtein@1.0.16: resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} engines: {node: '>= 4.9.1'} @@ -12464,6 +12666,12 @@ packages: jose@4.15.9: resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==} + jose@5.10.0: + resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} + + jose@6.1.0: + resolution: {integrity: sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==} + joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} @@ -12654,6 +12862,10 @@ packages: kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + kysely@0.28.8: + resolution: {integrity: sha512-QUOgl5ZrS9IRuhq5FvOKFSsD/3+IA6MLE81/bOOTRA/YQpKDza2sFdN5g6JCB9BOpqMJDGefLCQ9F12hRS13TA==} + engines: {node: '>=20.0.0'} + langium@3.3.1: resolution: {integrity: sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==} engines: {node: '>=16.0.0'} @@ -12705,68 +12917,74 @@ packages: light-my-request@5.14.0: resolution: {integrity: sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==} - lightningcss-darwin-arm64@1.28.2: - resolution: {integrity: sha512-/8cPSqZiusHSS+WQz0W4NuaqFjquys1x+NsdN/XOHb+idGHJSoJ7SoQTVl3DZuAgtPZwFZgRfb/vd1oi8uX6+g==} + lightningcss-android-arm64@1.30.2: + resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.30.2: + resolution: {integrity: sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] - lightningcss-darwin-x64@1.28.2: - resolution: {integrity: sha512-R7sFrXlgKjvoEG8umpVt/yutjxOL0z8KWf0bfPT3cYMOW4470xu5qSHpFdIOpRWwl3FKNMUdbKtMUjYt0h2j4g==} + lightningcss-darwin-x64@1.30.2: + resolution: {integrity: sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] - lightningcss-freebsd-x64@1.28.2: - resolution: {integrity: sha512-l2qrCT+x7crAY+lMIxtgvV10R8VurzHAoUZJaVFSlHrN8kRLTvEg9ObojIDIexqWJQvJcVVV3vfzsEynpiuvgA==} + lightningcss-freebsd-x64@1.30.2: + resolution: {integrity: sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.28.2: - resolution: {integrity: sha512-DKMzpICBEKnL53X14rF7hFDu8KKALUJtcKdFUCW5YOlGSiwRSgVoRjM97wUm/E0NMPkzrTi/rxfvt7ruNK8meg==} + lightningcss-linux-arm-gnueabihf@1.30.2: + resolution: {integrity: sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] - lightningcss-linux-arm64-gnu@1.28.2: - resolution: {integrity: sha512-nhfjYkfymWZSxdtTNMWyhFk2ImUm0X7NAgJWFwnsYPOfmtWQEapzG/DXZTfEfMjSzERNUNJoQjPAbdqgB+sjiw==} + lightningcss-linux-arm64-gnu@1.30.2: + resolution: {integrity: sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-arm64-musl@1.28.2: - resolution: {integrity: sha512-1SPG1ZTNnphWvAv8RVOymlZ8BDtAg69Hbo7n4QxARvkFVCJAt0cgjAw1Fox0WEhf4PwnyoOBaVH0Z5YNgzt4dA==} + lightningcss-linux-arm64-musl@1.30.2: + resolution: {integrity: sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [linux] - lightningcss-linux-x64-gnu@1.28.2: - resolution: {integrity: sha512-ZhQy0FcO//INWUdo/iEdbefntTdpPVQ0XJwwtdbBuMQe+uxqZoytm9M+iqR9O5noWFaxK+nbS2iR/I80Q2Ofpg==} + lightningcss-linux-x64-gnu@1.30.2: + resolution: {integrity: sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-linux-x64-musl@1.28.2: - resolution: {integrity: sha512-alb/j1NMrgQmSFyzTbN1/pvMPM+gdDw7YBuQ5VSgcFDypN3Ah0BzC2dTZbzwzaMdUVDszX6zH5MzjfVN1oGuww==} + lightningcss-linux-x64-musl@1.30.2: + resolution: {integrity: sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [linux] - lightningcss-win32-arm64-msvc@1.28.2: - resolution: {integrity: sha512-WnwcjcBeAt0jGdjlgbT9ANf30pF0C/QMb1XnLnH272DQU8QXh+kmpi24R55wmWBwaTtNAETZ+m35ohyeMiNt+g==} + lightningcss-win32-arm64-msvc@1.30.2: + resolution: {integrity: sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] - lightningcss-win32-x64-msvc@1.28.2: - resolution: {integrity: sha512-3piBifyT3avz22o6mDKywQC/OisH2yDK+caHWkiMsF82i3m5wDBadyCjlCQ5VNgzYkxrWZgiaxHDdd5uxsi0/A==} + lightningcss-win32-x64-msvc@1.30.2: + resolution: {integrity: sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] - lightningcss@1.28.2: - resolution: {integrity: sha512-ePLRrbt3fgjXI5VFZOLbvkLD5ZRuxGKm+wJ3ujCqBtL3NanDHPo/5zicR5uEKAPiIjBYF99BM4K4okvMznjkVA==} + lightningcss@1.30.2: + resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} engines: {node: '>= 12.0.0'} lilconfig@3.1.3: @@ -13647,6 +13865,10 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanostores@1.0.1: + resolution: {integrity: sha512-kNZ9xnoJYKg/AfxjrVL4SS0fKX++4awQReGqWnwTRHxeHGZ1FJFVgTqr/eMrNQdp0Tz7M7tG/TDaX8QfHDwVCw==} + engines: {node: ^20.0.0 || >=22.0.0} + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -13740,6 +13962,10 @@ packages: resolution: {integrity: sha512-mNcltoe1R8o7STTegSOHdnJNN7s5EUvhoS7ShnTHDyOSd+8H+UdWODq6qSv67PjC8Zc5JRT8+oLAMCr0SIXw7g==} engines: {node: ^16 || ^18 || >= 20} + node-addon-api@8.5.0: + resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==} + engines: {node: ^18 || ^20 || >= 21} + node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -13758,10 +13984,18 @@ packages: resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + node-gyp-build-optional-packages@5.2.2: resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} hasBin: true + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + node-gyp@10.0.1: resolution: {integrity: sha512-gg3/bHehQfZivQVfqIyy8wTdSymF9yTyP4CJifK73imyNMU8AIGQE2pUa7dNWfmMeG9cDVF2eehiRMv0LC1iAg==} engines: {node: ^16.14.0 || >=18.0.0} @@ -13773,6 +14007,12 @@ packages: node-releases@2.0.21: resolution: {integrity: sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==} + node-releases@2.0.26: + resolution: {integrity: sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==} + + node-rsa@1.1.1: + resolution: {integrity: sha512-Jd4cvbJMryN21r5HgxQOpMEqv+ooke/korixNNK3mGqfGJmy0M77WDDzo/05969+OkMy3XW1UuZsSmW9KQm7Fw==} + node-sql-parser@4.12.0: resolution: {integrity: sha512-WvHzITmtN5fx201c/cHX7RJvDaS9tTMpjE0TeYPrjH2bDAkoqMcDAUBuPQb7DU2Lhi5EZLbuWoRZnZDYYpx07w==} engines: {node: '>=8'} @@ -13882,6 +14122,11 @@ packages: nullthrows@1.1.1: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} + oauth2-mock-server@7.2.1: + resolution: {integrity: sha512-ZXL+VuJU2pvzehseq+7b47ZSN7p2Z7J5GoI793X0oECgdLYdol7tnBbTY/aUxuMkk+xpnE186ZzhnigwCAEBOQ==} + engines: {node: ^18.12 || ^20 || ^22, yarn: ^1.15.2} + hasBin: true + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -14115,6 +14360,9 @@ packages: resolution: {integrity: sha512-8KPLGT5g9s+olKMRTU9LFekLizkVIu9tes90O1/aigJ0T5LmyPqTzGJrETnSw3meSYg58YH7JTzhTTW/3z6VAw==} hasBin: true + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + param-case@3.0.4: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} @@ -14274,6 +14522,11 @@ packages: peerDependencies: pg: ^8 + pg-cursor@2.15.3: + resolution: {integrity: sha512-eHw63TsiGtFEfAd7tOTZ+TLy+i/2ePKS20H84qCQ+aQ60pve05Okon9tKMC+YN3j6XyeFoHnaim7Lt9WVafQsA==} + peerDependencies: + pg: ^8 + pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} @@ -14751,8 +15004,8 @@ packages: resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} engines: {node: '>=6'} - pvtsutils@1.3.2: - resolution: {integrity: sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ==} + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} pvutils@1.1.3: resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} @@ -15264,6 +15517,11 @@ packages: engines: {node: '>= 0.4'} hasBin: true + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + resolve@1.22.8: resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true @@ -15359,6 +15617,9 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rou3@0.5.1: + resolution: {integrity: sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ==} + roughjs@4.6.6: resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} @@ -15412,6 +15673,9 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + samlify@2.10.1: + resolution: {integrity: sha512-4zHbKKTvPnnqfGu4tks26K4fJjsY99ylsP7TPMobW5rggwcsxNlyhLE9ucxW3JFCsUcoKXb77QjQjwQo1TtRgw==} + sax@1.4.1: resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} @@ -15906,8 +16170,11 @@ packages: strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} - style-mod@4.1.2: - resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==} + strnum@2.1.1: + resolution: {integrity: sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==} + + style-mod@4.1.3: + resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==} style-to-js@1.1.17: resolution: {integrity: sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA==} @@ -16320,6 +16587,10 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + tsyringe@4.10.0: + resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} + engines: {node: '>= 6.0.0'} + tuf-js@2.2.0: resolution: {integrity: sha512-ZSDngmP1z6zw+FIkIBjvOp/II/mIub/O7Pp12j1WNsiCpg5R5wAc//i555bBQsE44O94btLt0xM/Zr2LQjwdCg==} engines: {node: ^16.14.0 || >=18.0.0} @@ -16465,6 +16736,9 @@ packages: resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} engines: {node: '>=0.10.0'} + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -16586,6 +16860,12 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + update-browserslist-db@1.1.4: + resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + upper-case-first@2.0.2: resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} @@ -17061,6 +17341,13 @@ packages: utf-8-validate: optional: true + xml-crypto@6.1.2: + resolution: {integrity: sha512-leBOVQdVi8FvPJrMYoum7Ici9qyxfE4kVi+AkpUoYCSXaQF4IlBm1cneTK9oAxR61LpYxTx7lNcsnBIeRpGW2w==} + engines: {node: '>=16'} + + xml-escape@1.1.0: + resolution: {integrity: sha512-B/T4sDK8Z6aUh/qNr7mjKAwwncIljFuUP+DO/D5hloYFj+90O88z8Wf7oSucZTHxBAsC1/CTP4rtx/x1Uf72Mg==} + xml@1.0.1: resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} @@ -17068,6 +17355,14 @@ packages: resolution: {integrity: sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==} engines: {node: '>=6.0'} + xpath@0.0.32: + resolution: {integrity: sha512-rxMJhSIoiO8vXcWvSifKqhvV96GjiD5wYb8/QHdoRyQvraTpp4IEv944nhGausZZ3u7dhQXteZuZbaqfpB7uYw==} + engines: {node: '>=0.6.0'} + + xpath@0.0.33: + resolution: {integrity: sha512-NNXnzrkDrAzalLhIUc01jO2mOzXGXh1JwPgkihcLLzw98c0WgYDmmjSh1Kl3wzaxSVWMuA+fe0WTWOBDWCBmNA==} + engines: {node: '>=0.6.0'} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -17166,6 +17461,9 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.1.12: + resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} + zrender@5.6.1: resolution: {integrity: sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==} @@ -17544,6 +17842,12 @@ snapshots: '@apollo/server': 5.0.0(graphql@16.9.0) express: 4.21.2 + '@authenio/xml-encryption@2.0.2': + dependencies: + '@xmldom/xmldom': 0.8.11 + escape-html: 1.0.3 + xpath: 0.0.32 + '@aws-crypto/crc32@5.2.0': dependencies: '@aws-crypto/util': 5.2.0 @@ -18848,6 +19152,43 @@ snapshots: bentocache: 1.1.0(patch_hash=98c0f93795fdd4f5eae32ee7915de8e9a346a24c3a917262b1f4551190f1a1af)(ioredis@5.4.2) prom-client: 15.1.3 + '@better-auth/core@1.3.29(patch_hash=8ab0ea888a8dd5e27ac74f518933c4deeb1815d41f31174635103c32ec5df160)(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1)': + dependencies: + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.18 + better-call: 1.0.19 + jose: 6.1.0 + kysely: 0.28.8 + nanostores: 1.0.1 + zod: 4.1.12 + + '@better-auth/sso@1.3.27(better-auth@1.3.29)': + dependencies: + '@better-fetch/fetch': 1.1.18 + better-auth: 1.3.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + fast-xml-parser: 5.3.0 + jose: 6.1.0 + oauth2-mock-server: 7.2.1 + samlify: 2.10.1 + zod: 4.1.12 + transitivePeerDependencies: + - supports-color + + '@better-auth/telemetry@1.3.29(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1)': + dependencies: + '@better-auth/core': 1.3.29(patch_hash=8ab0ea888a8dd5e27ac74f518933c4deeb1815d41f31174635103c32ec5df160)(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1) + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.18 + transitivePeerDependencies: + - better-call + - jose + - kysely + - nanostores + + '@better-auth/utils@0.3.0': {} + + '@better-fetch/fetch@1.1.18': {} + '@boringnode/bus@0.7.0(ioredis@5.4.2)': dependencies: '@paralleldrive/cuid2': 2.2.2 @@ -19057,21 +19398,22 @@ snapshots: '@codemirror/language@6.10.2': dependencies: - '@codemirror/state': 6.5.0 - '@codemirror/view': 6.36.1 - '@lezer/common': 1.2.3 - '@lezer/highlight': 1.2.1 + '@codemirror/state': 6.5.2 + '@codemirror/view': 6.38.6 + '@lezer/common': 1.3.0 + '@lezer/highlight': 1.2.2 '@lezer/lr': 1.4.2 - style-mod: 4.1.2 + style-mod: 4.1.3 - '@codemirror/state@6.5.0': + '@codemirror/state@6.5.2': dependencies: '@marijn/find-cluster-break': 1.0.2 - '@codemirror/view@6.36.1': + '@codemirror/view@6.38.6': dependencies: - '@codemirror/state': 6.5.0 - style-mod: 4.1.2 + '@codemirror/state': 6.5.2 + crelt: 1.0.6 + style-mod: 4.1.3 w3c-keyname: 2.2.8 '@colors/colors@1.5.0': @@ -19296,13 +19638,13 @@ snapshots: graphql: 16.9.0 tslib: 2.8.1 - '@envelop/response-cache@6.1.2(@envelop/core@5.3.1)(graphql@16.9.0)': + '@envelop/response-cache@6.1.2(@envelop/core@5.3.1)(graphql@16.11.0)': dependencies: '@envelop/core': 5.3.1 - '@graphql-tools/utils': 10.9.1(graphql@16.9.0) + '@graphql-tools/utils': 10.9.1(graphql@16.11.0) '@whatwg-node/fetch': 0.9.22 fast-json-stable-stringify: 2.1.0 - graphql: 16.9.0 + graphql: 16.11.0 lru-cache: 10.2.0 tslib: 2.8.1 @@ -20447,6 +20789,16 @@ snapshots: tslib: 2.8.1 value-or-promise: 1.0.12 + '@graphql-tools/executor@1.4.7(graphql@16.11.0)': + dependencies: + '@graphql-tools/utils': 10.9.1(graphql@16.11.0) + '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) + '@repeaterjs/repeater': 3.0.6 + '@whatwg-node/disposablestack': 0.0.6 + '@whatwg-node/promise-helpers': 1.3.1 + graphql: 16.11.0 + tslib: 2.8.1 + '@graphql-tools/executor@1.4.7(graphql@16.9.0)': dependencies: '@graphql-tools/utils': 10.9.1(graphql@16.9.0) @@ -20633,6 +20985,12 @@ snapshots: graphql: 16.9.0 tslib: 2.8.1 + '@graphql-tools/merge@9.1.1(graphql@16.11.0)': + dependencies: + '@graphql-tools/utils': 10.9.1(graphql@16.11.0) + graphql: 16.11.0 + tslib: 2.8.1 + '@graphql-tools/merge@9.1.1(graphql@16.9.0)': dependencies: '@graphql-tools/utils': 10.9.1(graphql@16.9.0) @@ -20669,6 +21027,13 @@ snapshots: graphql: 16.9.0 tslib: 2.8.1 + '@graphql-tools/schema@10.0.25(graphql@16.11.0)': + dependencies: + '@graphql-tools/merge': 9.1.1(graphql@16.11.0) + '@graphql-tools/utils': 10.9.1(graphql@16.11.0) + graphql: 16.11.0 + tslib: 2.8.1 + '@graphql-tools/schema@10.0.25(graphql@16.9.0)': dependencies: '@graphql-tools/merge': 9.1.1(graphql@16.9.0) @@ -20786,6 +21151,15 @@ snapshots: graphql: 16.9.0 tslib: 2.8.1 + '@graphql-tools/utils@10.9.1(graphql@16.11.0)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.11.0) + '@whatwg-node/promise-helpers': 1.3.1 + cross-inspect: 1.0.1 + dset: 3.1.4 + graphql: 16.11.0 + tslib: 2.8.1 + '@graphql-tools/utils@10.9.1(graphql@16.9.0)': dependencies: '@graphql-typed-document-node/core': 3.2.0(graphql@16.9.0) @@ -20836,6 +21210,10 @@ snapshots: tslib: 2.8.1 value-or-promise: 1.0.12 + '@graphql-typed-document-node/core@3.2.0(graphql@16.11.0)': + dependencies: + graphql: 16.11.0 + '@graphql-typed-document-node/core@3.2.0(graphql@16.9.0)': dependencies: graphql: 16.9.0 @@ -20848,28 +21226,28 @@ snapshots: dependencies: tslib: 2.8.1 - '@graphql-yoga/plugin-defer-stream@3.7.0(graphql-yoga@5.13.3(graphql@16.9.0))(graphql@16.9.0)': + '@graphql-yoga/plugin-defer-stream@3.7.0(graphql-yoga@5.13.3(graphql@16.11.0))(graphql@16.11.0)': dependencies: - '@graphql-tools/utils': 10.9.1(graphql@16.9.0) - graphql: 16.9.0 - graphql-yoga: 5.13.3(graphql@16.9.0) + '@graphql-tools/utils': 10.9.1(graphql@16.11.0) + graphql: 16.11.0 + graphql-yoga: 5.13.3(graphql@16.11.0) - '@graphql-yoga/plugin-disable-introspection@2.7.0(graphql-yoga@5.13.3(graphql@16.9.0))(graphql@16.9.0)': + '@graphql-yoga/plugin-disable-introspection@2.7.0(graphql-yoga@5.13.3(graphql@16.11.0))(graphql@16.11.0)': dependencies: - graphql: 16.9.0 - graphql-yoga: 5.13.3(graphql@16.9.0) + graphql: 16.11.0 + graphql-yoga: 5.13.3(graphql@16.11.0) - '@graphql-yoga/plugin-graphql-sse@3.7.0(graphql-yoga@5.13.3(graphql@16.9.0))(graphql@16.9.0)': + '@graphql-yoga/plugin-graphql-sse@3.7.0(graphql-yoga@5.13.3(graphql@16.11.0))(graphql@16.11.0)': dependencies: - graphql: 16.9.0 - graphql-sse: 2.5.3(graphql@16.9.0) - graphql-yoga: 5.13.3(graphql@16.9.0) + graphql: 16.11.0 + graphql-sse: 2.5.3(graphql@16.11.0) + graphql-yoga: 5.13.3(graphql@16.11.0) - '@graphql-yoga/plugin-persisted-operations@3.9.0(@graphql-tools/utils@10.9.1(graphql@16.9.0))(graphql-yoga@5.13.3(graphql@16.9.0))(graphql@16.9.0)': + '@graphql-yoga/plugin-persisted-operations@3.9.0(@graphql-tools/utils@10.9.1(graphql@16.11.0))(graphql-yoga@5.13.3(graphql@16.11.0))(graphql@16.11.0)': dependencies: - '@graphql-tools/utils': 10.9.1(graphql@16.9.0) - graphql: 16.9.0 - graphql-yoga: 5.13.3(graphql@16.9.0) + '@graphql-tools/utils': 10.9.1(graphql@16.11.0) + graphql: 16.11.0 + graphql-yoga: 5.13.3(graphql@16.11.0) '@graphql-yoga/plugin-response-cache@3.15.4(graphql-yoga@5.13.3(graphql@16.9.0))(graphql@16.9.0)': dependencies: @@ -20879,11 +21257,11 @@ snapshots: graphql: 16.9.0 graphql-yoga: 5.13.3(graphql@16.9.0) - '@graphql-yoga/plugin-response-cache@3.9.0(@envelop/core@5.3.1)(graphql-yoga@5.13.3(graphql@16.9.0))(graphql@16.9.0)': + '@graphql-yoga/plugin-response-cache@3.9.0(@envelop/core@5.3.1)(graphql-yoga@5.13.3(graphql@16.11.0))(graphql@16.11.0)': dependencies: - '@envelop/response-cache': 6.1.2(@envelop/core@5.3.1)(graphql@16.9.0) - graphql: 16.9.0 - graphql-yoga: 5.13.3(graphql@16.9.0) + '@envelop/response-cache': 6.1.2(@envelop/core@5.3.1)(graphql@16.11.0) + graphql: 16.11.0 + graphql-yoga: 5.13.3(graphql@16.11.0) transitivePeerDependencies: - '@envelop/core' @@ -20960,6 +21338,8 @@ snapshots: react: 19.0.0 react-dom: 19.0.0(react@19.0.0) + '@hexagon/base64@1.1.28': {} + '@hookform/resolvers@3.10.0(react-hook-form@7.54.2(react@18.3.1))': dependencies: react-hook-form: 7.54.2(react@18.3.1) @@ -21273,14 +21653,20 @@ snapshots: '@josephg/resolvable@1.0.1': {} - '@joshwooding/vite-plugin-react-docgen-typescript@0.4.2(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0))': + '@joshwooding/vite-plugin-react-docgen-typescript@0.4.2(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0))': dependencies: magic-string: 0.27.0 react-docgen-typescript: 2.2.2(typescript@5.7.3) - vite: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + vite: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) optionalDependencies: typescript: 5.7.3 + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + optional: true + '@jridgewell/gen-mapping@0.3.8': dependencies: '@jridgewell/set-array': 1.2.1 @@ -21289,23 +21675,35 @@ snapshots: '@jridgewell/resolve-uri@3.1.1': {} + '@jridgewell/resolve-uri@3.1.2': + optional: true + '@jridgewell/set-array@1.2.1': {} - '@jridgewell/source-map@0.3.6': + '@jridgewell/source-map@0.3.11': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 optional: true '@jridgewell/sourcemap-codec@1.4.15': {} '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.5': + optional: true + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + optional: true + '@jridgewell/trace-mapping@0.3.9': dependencies: '@jridgewell/resolve-uri': 3.1.1 @@ -21331,15 +21729,17 @@ snapshots: - ts-node - typescript - '@lezer/common@1.2.3': {} + '@levischuck/tiny-cbor@0.2.11': {} + + '@lezer/common@1.3.0': {} - '@lezer/highlight@1.2.1': + '@lezer/highlight@1.2.2': dependencies: - '@lezer/common': 1.2.3 + '@lezer/common': 1.3.0 '@lezer/lr@1.4.2': dependencies: - '@lezer/common': 1.2.3 + '@lezer/common': 1.3.0 '@lit-labs/ssr-dom-shim@1.4.0': {} @@ -21612,8 +22012,12 @@ snapshots: '@next/swc-win32-x64-msvc@15.5.3': optional: true + '@noble/ciphers@2.0.1': {} + '@noble/hashes@1.7.1': {} + '@noble/hashes@2.0.1': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -23035,10 +23439,86 @@ snapshots: '@parcel/watcher-win32-ia32': 2.5.1 '@parcel/watcher-win32-x64': 2.5.1 - '@peculiar/asn1-schema@2.3.0': + '@peculiar/asn1-android@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-cms@2.5.0': dependencies: - asn1js: 3.0.5 - pvtsutils: 1.3.2 + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + '@peculiar/asn1-x509-attr': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-csr@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-ecc@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-pfx@2.5.0': + dependencies: + '@peculiar/asn1-cms': 2.5.0 + '@peculiar/asn1-pkcs8': 2.5.0 + '@peculiar/asn1-rsa': 2.5.0 + '@peculiar/asn1-schema': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs8@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs9@2.5.0': + dependencies: + '@peculiar/asn1-cms': 2.5.0 + '@peculiar/asn1-pfx': 2.5.0 + '@peculiar/asn1-pkcs8': 2.5.0 + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + '@peculiar/asn1-x509-attr': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-rsa@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-schema@2.5.0': + dependencies: + asn1js: 3.0.6 + pvtsutils: 1.3.6 + tslib: 2.8.1 + + '@peculiar/asn1-x509-attr@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-x509@2.5.0': + dependencies: + '@peculiar/asn1-schema': 2.5.0 + asn1js: 3.0.6 + pvtsutils: 1.3.6 tslib: 2.8.1 '@peculiar/json-schema@1.1.12': @@ -23047,12 +23527,26 @@ snapshots: '@peculiar/webcrypto@1.4.0': dependencies: - '@peculiar/asn1-schema': 2.3.0 + '@peculiar/asn1-schema': 2.5.0 '@peculiar/json-schema': 1.1.12 - pvtsutils: 1.3.2 + pvtsutils: 1.3.6 tslib: 2.8.1 webcrypto-core: 1.7.5 + '@peculiar/x509@1.14.0': + dependencies: + '@peculiar/asn1-cms': 2.5.0 + '@peculiar/asn1-csr': 2.5.0 + '@peculiar/asn1-ecc': 2.5.0 + '@peculiar/asn1-pkcs9': 2.5.0 + '@peculiar/asn1-rsa': 2.5.0 + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + pvtsutils: 1.3.6 + reflect-metadata: 0.2.2 + tslib: 2.8.1 + tsyringe: 4.10.0 + '@pkgjs/parseargs@0.11.0': optional: true @@ -24739,6 +25233,19 @@ snapshots: '@sigstore/core': 1.0.0 '@sigstore/protobuf-specs': 0.3.0 + '@simplewebauthn/browser@13.2.2': {} + + '@simplewebauthn/server@13.2.2': + dependencies: + '@hexagon/base64': 1.1.28 + '@levischuck/tiny-cbor': 0.2.11 + '@peculiar/asn1-android': 2.5.0 + '@peculiar/asn1-ecc': 2.5.0 + '@peculiar/asn1-rsa': 2.5.0 + '@peculiar/asn1-schema': 2.5.0 + '@peculiar/asn1-x509': 2.5.0 + '@peculiar/x509': 1.14.0 + '@sinclair/typebox@0.27.8': {} '@sinclair/typebox@0.34.41': {} @@ -25486,13 +25993,13 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) - '@storybook/builder-vite@8.4.7(storybook@8.4.7(prettier@3.4.2))(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0))': + '@storybook/builder-vite@8.4.7(storybook@8.4.7(prettier@3.4.2))(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0))': dependencies: '@storybook/csf-plugin': 8.4.7(storybook@8.4.7(prettier@3.4.2)) browser-assert: 1.2.1 storybook: 8.4.7(prettier@3.4.2) ts-dedent: 2.2.0 - vite: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + vite: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) '@storybook/components@8.4.7(storybook@8.4.7(prettier@3.4.2))': dependencies: @@ -25554,11 +26061,11 @@ snapshots: react-dom: 18.3.1(react@18.3.1) storybook: 8.4.7(prettier@3.4.2) - '@storybook/react-vite@8.4.7(@storybook/test@8.4.7(storybook@8.4.7(prettier@3.4.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7(prettier@3.4.2))(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0))': + '@storybook/react-vite@8.4.7(@storybook/test@8.4.7(storybook@8.4.7(prettier@3.4.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7(prettier@3.4.2))(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0))': dependencies: - '@joshwooding/vite-plugin-react-docgen-typescript': 0.4.2(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) + '@joshwooding/vite-plugin-react-docgen-typescript': 0.4.2(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) '@rollup/pluginutils': 5.0.2 - '@storybook/builder-vite': 8.4.7(storybook@8.4.7(prettier@3.4.2))(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) + '@storybook/builder-vite': 8.4.7(storybook@8.4.7(prettier@3.4.2))(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) '@storybook/react': 8.4.7(@storybook/test@8.4.7(storybook@8.4.7(prettier@3.4.2)))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.4.7(prettier@3.4.2))(typescript@5.7.3) find-up: 5.0.0 magic-string: 0.30.10 @@ -25568,7 +26075,7 @@ snapshots: resolve: 1.22.8 storybook: 8.4.7(prettier@3.4.2) tsconfig-paths: 4.2.0 - vite: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + vite: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) transitivePeerDependencies: - '@storybook/test' - rollup @@ -25979,6 +26486,10 @@ snapshots: dependencies: '@babel/types': 7.26.10 + '@types/bcrypt@6.0.0': + dependencies: + '@types/node': 22.10.5 + '@types/bcryptjs@2.4.6': {} '@types/body-parser@1.19.6': @@ -26564,14 +27075,14 @@ snapshots: dependencies: graphql: 16.9.0 - '@vitejs/plugin-react@4.3.4(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0))': + '@vitejs/plugin-react@4.3.4(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0))': dependencies: '@babel/core': 7.26.0 '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.0) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + vite: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) transitivePeerDependencies: - supports-color @@ -26590,13 +27101,13 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0))': + '@vitest/mocker@3.2.4(vite@6.3.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 6.3.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + vite: 6.3.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) '@vitest/pretty-format@2.0.5': dependencies: @@ -26751,6 +27262,10 @@ snapshots: '@whatwg-node/fetch': 0.10.6 tslib: 2.8.1 + '@xmldom/is-dom-node@1.0.1': {} + + '@xmldom/xmldom@0.8.11': {} + '@xmldom/xmldom@0.9.8': {} '@xyflow/react@12.4.4(@types/react@18.3.18)(immer@10.1.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': @@ -26805,6 +27320,9 @@ snapshots: acorn@8.14.0: {} + acorn@8.15.0: + optional: true + addressparser@1.0.1: {} agent-base@6.0.2: @@ -26997,9 +27515,9 @@ snapshots: dependencies: safer-buffer: 2.1.2 - asn1js@3.0.5: + asn1js@3.0.6: dependencies: - pvtsutils: 1.3.2 + pvtsutils: 1.3.6 pvutils: 1.1.3 tslib: 2.8.1 @@ -27123,12 +27641,23 @@ snapshots: base64-js@1.5.1: {} + baseline-browser-mapping@2.8.19: {} + baseline-browser-mapping@2.8.3: {} + basic-auth@2.0.1: + dependencies: + safe-buffer: 5.1.2 + bcrypt-pbkdf@1.0.2: dependencies: tweetnacl: 0.14.5 + bcrypt@6.0.0: + dependencies: + node-addon-api: 8.5.0 + node-gyp-build: 4.8.4 + bcryptjs@2.4.3: {} before-after-hook@3.0.2: {} @@ -27145,6 +27674,34 @@ snapshots: optionalDependencies: ioredis: 5.4.2 + better-auth@1.3.29(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@better-auth/core': 1.3.29(patch_hash=8ab0ea888a8dd5e27ac74f518933c4deeb1815d41f31174635103c32ec5df160)(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.18)(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1) + '@better-auth/telemetry': 1.3.29(better-call@1.0.19)(jose@6.1.0)(kysely@0.28.8)(nanostores@1.0.1) + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.18 + '@noble/ciphers': 2.0.1 + '@noble/hashes': 2.0.1 + '@simplewebauthn/browser': 13.2.2 + '@simplewebauthn/server': 13.2.2 + better-call: 1.0.19 + defu: 6.1.4 + jose: 6.1.0 + kysely: 0.28.8 + nanostores: 1.0.1 + zod: 4.1.12 + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + better-call@1.0.19: + dependencies: + '@better-auth/utils': 0.3.0 + '@better-fetch/fetch': 1.1.18 + rou3: 0.5.1 + set-cookie-parser: 2.7.1 + uncrypto: 0.1.3 + better-opn@3.0.2: dependencies: open: 8.4.2 @@ -27270,6 +27827,14 @@ snapshots: node-releases: 2.0.21 update-browserslist-db: 1.1.3(browserslist@4.26.0) + browserslist@4.27.0: + dependencies: + baseline-browser-mapping: 2.8.19 + caniuse-lite: 1.0.30001751 + electron-to-chromium: 1.5.239 + node-releases: 2.0.26 + update-browserslist-db: 1.1.4(browserslist@4.27.0) + bser@2.1.1: dependencies: node-int64: 0.4.0 @@ -27437,8 +28002,12 @@ snapshots: camelcase@5.3.1: {} + camelcase@6.3.0: {} + caniuse-lite@1.0.30001741: {} + caniuse-lite@1.0.30001751: {} + capital-case@1.0.4: dependencies: no-case: 3.0.4 @@ -27900,6 +28469,8 @@ snapshots: create-require@1.1.1: {} + crelt@1.0.6: {} + cron-parser@4.9.0: dependencies: luxon: 3.5.0 @@ -28358,6 +28929,8 @@ snapshots: detect-libc@2.1.0: optional: true + detect-libc@2.1.2: {} + detect-newline@4.0.1: {} detect-node-es@1.1.0: {} @@ -28530,6 +29103,8 @@ snapshots: electron-to-chromium@1.5.218: {} + electron-to-chromium@1.5.239: {} + emoji-regex-xs@1.0.0: {} emoji-regex@10.3.0: {} @@ -29304,6 +29879,10 @@ snapshots: dependencies: strnum: 1.0.5 + fast-xml-parser@5.3.0: + dependencies: + strnum: 2.1.1 + fastest-levenshtein@1.0.16: {} fastify-plugin@4.5.1: {} @@ -30053,6 +30632,10 @@ snapshots: graphql: 16.9.0 tslib: 2.8.1 + graphql-sse@2.5.3(graphql@16.11.0): + dependencies: + graphql: 16.11.0 + graphql-sse@2.5.3(graphql@16.9.0): dependencies: graphql: 16.9.0 @@ -30070,6 +30653,10 @@ snapshots: dependencies: graphql: 16.9.0 + graphql-ws@5.16.1(graphql@16.11.0): + dependencies: + graphql: 16.11.0 + graphql-ws@5.16.1(graphql@16.9.0): dependencies: graphql: 16.9.0 @@ -30095,6 +30682,23 @@ snapshots: lru-cache: 10.2.0 tslib: 2.8.1 + graphql-yoga@5.13.3(graphql@16.11.0): + dependencies: + '@envelop/core': 5.2.3 + '@envelop/instrumentation': 1.0.0 + '@graphql-tools/executor': 1.4.7(graphql@16.11.0) + '@graphql-tools/schema': 10.0.25(graphql@16.11.0) + '@graphql-tools/utils': 10.9.1(graphql@16.11.0) + '@graphql-yoga/logger': 2.0.1 + '@graphql-yoga/subscription': 5.0.4 + '@whatwg-node/fetch': 0.10.6 + '@whatwg-node/promise-helpers': 1.3.0 + '@whatwg-node/server': 0.10.3 + dset: 3.1.4 + graphql: 16.11.0 + lru-cache: 10.2.0 + tslib: 2.8.1 + graphql-yoga@5.13.3(graphql@16.9.0): dependencies: '@envelop/core': 5.2.3 @@ -30883,6 +31487,10 @@ snapshots: jose@4.15.9: {} + jose@5.10.0: {} + + jose@6.1.0: {} + joycon@3.1.1: {} js-beautify@1.14.6: @@ -31074,6 +31682,8 @@ snapshots: kolorist@1.8.0: {} + kysely@0.28.8: {} + langium@3.3.1: dependencies: chevrotain: 11.0.3 @@ -31142,50 +31752,54 @@ snapshots: process-warning: 3.0.0 set-cookie-parser: 2.7.1 - lightningcss-darwin-arm64@1.28.2: + lightningcss-android-arm64@1.30.2: + optional: true + + lightningcss-darwin-arm64@1.30.2: optional: true - lightningcss-darwin-x64@1.28.2: + lightningcss-darwin-x64@1.30.2: optional: true - lightningcss-freebsd-x64@1.28.2: + lightningcss-freebsd-x64@1.30.2: optional: true - lightningcss-linux-arm-gnueabihf@1.28.2: + lightningcss-linux-arm-gnueabihf@1.30.2: optional: true - lightningcss-linux-arm64-gnu@1.28.2: + lightningcss-linux-arm64-gnu@1.30.2: optional: true - lightningcss-linux-arm64-musl@1.28.2: + lightningcss-linux-arm64-musl@1.30.2: optional: true - lightningcss-linux-x64-gnu@1.28.2: + lightningcss-linux-x64-gnu@1.30.2: optional: true - lightningcss-linux-x64-musl@1.28.2: + lightningcss-linux-x64-musl@1.30.2: optional: true - lightningcss-win32-arm64-msvc@1.28.2: + lightningcss-win32-arm64-msvc@1.30.2: optional: true - lightningcss-win32-x64-msvc@1.28.2: + lightningcss-win32-x64-msvc@1.30.2: optional: true - lightningcss@1.28.2: + lightningcss@1.30.2: dependencies: - detect-libc: 1.0.3 + detect-libc: 2.1.2 optionalDependencies: - lightningcss-darwin-arm64: 1.28.2 - lightningcss-darwin-x64: 1.28.2 - lightningcss-freebsd-x64: 1.28.2 - lightningcss-linux-arm-gnueabihf: 1.28.2 - lightningcss-linux-arm64-gnu: 1.28.2 - lightningcss-linux-arm64-musl: 1.28.2 - lightningcss-linux-x64-gnu: 1.28.2 - lightningcss-linux-x64-musl: 1.28.2 - lightningcss-win32-arm64-msvc: 1.28.2 - lightningcss-win32-x64-msvc: 1.28.2 + lightningcss-android-arm64: 1.30.2 + lightningcss-darwin-arm64: 1.30.2 + lightningcss-darwin-x64: 1.30.2 + lightningcss-freebsd-x64: 1.30.2 + lightningcss-linux-arm-gnueabihf: 1.30.2 + lightningcss-linux-arm64-gnu: 1.30.2 + lightningcss-linux-arm64-musl: 1.30.2 + lightningcss-linux-x64-gnu: 1.30.2 + lightningcss-linux-x64-musl: 1.30.2 + lightningcss-win32-arm64-msvc: 1.30.2 + lightningcss-win32-x64-msvc: 1.30.2 lilconfig@3.1.3: {} @@ -32550,6 +33164,8 @@ snapshots: nanoid@3.3.8: {} + nanostores@1.0.1: {} + natural-compare@1.4.0: {} natural-orderby@2.0.3: {} @@ -32694,6 +33310,8 @@ snapshots: node-addon-api@7.1.0: {} + node-addon-api@8.5.0: {} + node-domexception@1.0.0: {} node-fetch@2.6.12(encoding@0.1.13): @@ -32708,11 +33326,15 @@ snapshots: fetch-blob: 3.2.0 formdata-polyfill: 4.0.10 + node-forge@1.3.1: {} + node-gyp-build-optional-packages@5.2.2: dependencies: detect-libc: 2.0.3 optional: true + node-gyp-build@4.8.4: {} + node-gyp@10.0.1: dependencies: env-paths: 2.2.1 @@ -32732,6 +33354,12 @@ snapshots: node-releases@2.0.21: {} + node-releases@2.0.26: {} + + node-rsa@1.1.1: + dependencies: + asn1: 0.2.6 + node-sql-parser@4.12.0: dependencies: big-integer: 1.6.51 @@ -32848,6 +33476,16 @@ snapshots: nullthrows@1.1.1: {} + oauth2-mock-server@7.2.1: + dependencies: + basic-auth: 2.0.1 + cors: 2.8.5 + express: 4.21.2 + is-plain-object: 5.0.0 + jose: 5.10.0 + transitivePeerDependencies: + - supports-color + object-assign@4.1.1: {} object-hash@3.0.0: {} @@ -33123,6 +33761,8 @@ snapshots: '@pagefind/linux-x64': 1.3.0 '@pagefind/windows-x64': 1.3.0 + pako@1.0.11: {} + param-case@3.0.4: dependencies: dot-case: 3.0.4 @@ -33299,6 +33939,10 @@ snapshots: dependencies: pg: 8.13.1 + pg-cursor@2.15.3(pg@8.13.1): + dependencies: + pg: 8.13.1 + pg-int8@1.0.1: {} pg-minify@1.6.5: {} @@ -33324,7 +33968,7 @@ snapshots: pg-query-stream@4.7.0(pg@8.13.1): dependencies: pg: 8.13.1 - pg-cursor: 2.12.1(pg@8.13.1) + pg-cursor: 2.15.3(pg@8.13.1) pg-types@2.2.0: dependencies: @@ -33456,7 +34100,7 @@ snapshots: postcss: 8.4.49 postcss-value-parser: 4.2.0 read-cache: 1.0.0 - resolve: 1.22.10 + resolve: 1.22.11 postcss-js@4.0.1(postcss@8.4.49): dependencies: @@ -33465,8 +34109,8 @@ snapshots: postcss-lightningcss@1.0.1(postcss@8.4.49): dependencies: - browserslist: 4.26.0 - lightningcss: 1.28.2 + browserslist: 4.27.0 + lightningcss: 1.30.2 postcss: 8.4.49 postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.13.5)(@types/node@22.10.5)(typescript@5.7.3)): @@ -33716,7 +34360,7 @@ snapshots: punycode@2.1.1: {} - pvtsutils@1.3.2: + pvtsutils@1.3.6: dependencies: tslib: 2.8.1 @@ -34357,6 +35001,12 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + resolve@1.22.8: dependencies: is-core-module: 2.13.1 @@ -34509,6 +35159,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.50.2 fsevents: 2.3.3 + rou3@0.5.1: {} + roughjs@4.6.6: dependencies: hachure-fill: 0.5.2 @@ -34570,6 +35222,20 @@ snapshots: safer-buffer@2.1.2: {} + samlify@2.10.1: + dependencies: + '@authenio/xml-encryption': 2.0.2 + '@xmldom/xmldom': 0.8.11 + camelcase: 6.3.0 + node-forge: 1.3.1 + node-rsa: 1.1.1 + pako: 1.0.11 + uuid: 8.3.2 + xml: 1.0.1 + xml-crypto: 6.1.2 + xml-escape: 1.1.0 + xpath: 0.0.32 + sax@1.4.1: optional: true @@ -35171,7 +35837,9 @@ snapshots: strnum@1.0.5: {} - style-mod@4.1.2: {} + strnum@2.1.1: {} + + style-mod@4.1.3: {} style-to-js@1.1.17: dependencies: @@ -35350,8 +36018,8 @@ snapshots: terser@5.37.0: dependencies: - '@jridgewell/source-map': 0.3.6 - acorn: 8.14.0 + '@jridgewell/source-map': 0.3.11 + acorn: 8.15.0 commander: 2.20.3 source-map-support: 0.5.21 optional: true @@ -35608,6 +36276,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + tsyringe@4.10.0: + dependencies: + tslib: 1.14.1 + tuf-js@2.2.0: dependencies: '@tufjs/models': 2.0.0 @@ -35752,6 +36424,8 @@ snapshots: unc-path-regex@0.1.2: {} + uncrypto@0.1.3: {} + undici-types@6.19.8: {} undici-types@6.20.0: {} @@ -35925,6 +36599,12 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + update-browserslist-db@1.1.4(browserslist@4.27.0): + dependencies: + browserslist: 4.27.0 + escalade: 3.2.0 + picocolors: 1.1.1 + upper-case-first@2.0.2: dependencies: tslib: 2.8.1 @@ -36122,13 +36802,13 @@ snapshots: d3-time: 3.1.0 d3-timer: 3.0.1 - vite-node@3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0): + vite-node@3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0): dependencies: cac: 6.7.14 debug: 4.4.1(supports-color@8.1.1) es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + vite: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) transitivePeerDependencies: - '@types/node' - jiti @@ -36143,18 +36823,18 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@5.1.4(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)): + vite-tsconfig-paths@5.1.4(typescript@5.7.3)(vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)): dependencies: debug: 4.3.7(supports-color@8.1.1) globrex: 0.1.2 tsconfck: 3.0.3(typescript@5.7.3) optionalDependencies: - vite: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + vite: 7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) transitivePeerDependencies: - supports-color - typescript - vite@6.3.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0): + vite@6.3.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0): dependencies: esbuild: 0.25.9 fdir: 6.4.4(picomatch@4.0.2) @@ -36167,12 +36847,12 @@ snapshots: fsevents: 2.3.3 jiti: 2.3.3 less: 4.2.0 - lightningcss: 1.28.2 + lightningcss: 1.30.2 terser: 5.37.0 tsx: 4.19.2 yaml: 2.5.0 - vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0): + vite@7.1.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -36185,16 +36865,16 @@ snapshots: fsevents: 2.3.3 jiti: 2.3.3 less: 4.2.0 - lightningcss: 1.28.2 + lightningcss: 1.30.2 terser: 5.37.0 tsx: 4.19.2 yaml: 2.5.0 - vitest@3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0): + vitest@3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) + '@vitest/mocker': 3.2.4(vite@6.3.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -36212,8 +36892,8 @@ snapshots: tinyglobby: 0.2.14 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 6.3.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) - vite-node: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.28.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + vite: 6.3.5(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) + vite-node: 3.2.4(@types/node@22.10.5)(jiti@2.3.3)(less@4.2.0)(lightningcss@1.30.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.5.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.10.5 @@ -36269,10 +36949,10 @@ snapshots: webcrypto-core@1.7.5: dependencies: - '@peculiar/asn1-schema': 2.3.0 + '@peculiar/asn1-schema': 2.5.0 '@peculiar/json-schema': 1.1.12 - asn1js: 3.0.5 - pvtsutils: 1.3.2 + asn1js: 3.0.6 + pvtsutils: 1.3.6 tslib: 2.8.1 webidl-conversions@3.0.1: {} @@ -36443,10 +37123,22 @@ snapshots: ws@8.18.0: {} + xml-crypto@6.1.2: + dependencies: + '@xmldom/is-dom-node': 1.0.1 + '@xmldom/xmldom': 0.8.11 + xpath: 0.0.33 + + xml-escape@1.1.0: {} + xml@1.0.1: {} xmlbuilder@13.0.2: {} + xpath@0.0.32: {} + + xpath@0.0.33: {} + xtend@4.0.2: {} y18n@4.0.3: {} @@ -36556,6 +37248,8 @@ snapshots: zod@3.25.76: {} + zod@4.1.12: {} + zrender@5.6.1: dependencies: tslib: 2.3.0