Add AuthCallbackService to handle auth callbacks in Supabase (#25)
* Add AuthCallbackService to handle auth callbacks in Supabase Created a new service, AuthCallbackService, in the Supabase package to centralize the handling of authentication callbacks. This service handles two main tasks: verifying the token hash for user email verification and exchanging the authentication code for a session. Code in the web app routes were updated to utilize this new service, improving code organization and reusability. * Remove CSRF Token Meta component and add Jaeger exporter The CSRF Token Meta component was removed from the application. Instead, CSRF tokens are now included in the root metadata of the application. Additionally, the "@opentelemetry/exporter-jaeger" package was added as a dependency to the Sentry monitoring package. This enables the tracing of application requests via Jaeger. * Refactor README.md and remove redundant content Removed the excessive content and detailed instruction from the README.md file. The documentation has been moved to a more suitable and detailed location elsewhere. * Update package dependencies in sentry/package.json An ordering change has been made in the dependencies within the sentry/package.json file. The "@opentelemetry/exporter-jaeger" dependency was moved to its correct alphabetical order. No version changes were made.
This commit is contained in:
committed by
GitHub
parent
3cf3c263bc
commit
048ab96cbc
@@ -1,96 +1,18 @@
|
||||
import { redirect } from 'next/navigation';
|
||||
import type { NextRequest } from 'next/server';
|
||||
|
||||
import { getLogger } from '@kit/shared/logger';
|
||||
import { createAuthCallbackService } from '@kit/supabase/auth';
|
||||
import { getSupabaseRouteHandlerClient } from '@kit/supabase/route-handler-client';
|
||||
|
||||
import pathsConfig from '~/config/paths.config';
|
||||
|
||||
const defaultNextUrl = pathsConfig.app.home;
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const requestUrl = new URL(request.url);
|
||||
const searchParams = requestUrl.searchParams;
|
||||
const service = createAuthCallbackService(getSupabaseRouteHandlerClient());
|
||||
|
||||
const authCode = searchParams.get('code');
|
||||
const error = searchParams.get('error');
|
||||
const nextUrlPathFromParams = searchParams.get('next');
|
||||
const inviteToken = searchParams.get('invite_token');
|
||||
const { nextPath } = await service.exchangeCodeForSession(request, {
|
||||
joinTeamPath: pathsConfig.app.joinTeam,
|
||||
redirectPath: pathsConfig.app.home,
|
||||
});
|
||||
|
||||
let nextUrl = nextUrlPathFromParams ?? defaultNextUrl;
|
||||
|
||||
// if we have an invite token, we redirect to the join team page
|
||||
// instead of the default next url. This is because the user is trying
|
||||
// to join a team and we want to make sure they are redirected to the
|
||||
// correct page.
|
||||
if (inviteToken) {
|
||||
nextUrl = `${pathsConfig.app.joinTeam}?invite_token=${inviteToken}`;
|
||||
}
|
||||
|
||||
if (authCode) {
|
||||
const client = getSupabaseRouteHandlerClient();
|
||||
|
||||
try {
|
||||
const { error } = await client.auth.exchangeCodeForSession(authCode);
|
||||
|
||||
// if we have an error, we redirect to the error page
|
||||
if (error) {
|
||||
return onError({ error: error.message });
|
||||
}
|
||||
} catch (error) {
|
||||
const logger = await getLogger();
|
||||
|
||||
logger.error(
|
||||
{
|
||||
error,
|
||||
name: `auth.callback`,
|
||||
},
|
||||
`An error occurred while exchanging code for session`,
|
||||
);
|
||||
|
||||
const message = error instanceof Error ? error.message : error;
|
||||
|
||||
return onError({ error: message as string });
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return onError({ error });
|
||||
}
|
||||
|
||||
return redirect(nextUrl);
|
||||
}
|
||||
|
||||
async function onError({ error }: { error: string }) {
|
||||
const errorMessage = getAuthErrorMessage(error);
|
||||
const logger = await getLogger();
|
||||
|
||||
logger.error(
|
||||
{
|
||||
error,
|
||||
name: `auth.callback`,
|
||||
},
|
||||
`An error occurred while signing user in`,
|
||||
);
|
||||
|
||||
const redirectUrl = `/auth/callback/error?error=${errorMessage}`;
|
||||
|
||||
return redirect(redirectUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given error message indicates a verifier error.
|
||||
* We check for this specific error because it's highly likely that the
|
||||
* user is trying to sign in using a different browser than the one they
|
||||
* used to request the sign in link. This is a common mistake, so we
|
||||
* want to provide a helpful error message.
|
||||
*/
|
||||
function isVerifierError(error: string) {
|
||||
return error.includes('both auth code and code verifier should be non-empty');
|
||||
}
|
||||
|
||||
function getAuthErrorMessage(error: string) {
|
||||
return isVerifierError(error)
|
||||
? `auth:errors.codeVerifierMismatch`
|
||||
: `auth:authenticationErrorAlertBody`;
|
||||
return redirect(nextPath);
|
||||
}
|
||||
|
||||
@@ -1,51 +1,17 @@
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
|
||||
import { type EmailOtpType } from '@supabase/supabase-js';
|
||||
|
||||
import { createAuthCallbackService } from '@kit/supabase/auth';
|
||||
import { getSupabaseRouteHandlerClient } from '@kit/supabase/route-handler-client';
|
||||
|
||||
import pathsConfig from '~/config/paths.config';
|
||||
|
||||
const defaultNextUrl = pathsConfig.app.home;
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const service = createAuthCallbackService(getSupabaseRouteHandlerClient());
|
||||
|
||||
const token_hash = searchParams.get('token_hash');
|
||||
const type = searchParams.get('type') as EmailOtpType | null;
|
||||
const next = searchParams.get('next') ?? defaultNextUrl;
|
||||
const callbackParam = searchParams.get('callback');
|
||||
const callbackUrl = callbackParam ? new URL(callbackParam) : null;
|
||||
const inviteToken = callbackUrl?.searchParams.get('invite_token');
|
||||
const redirectTo = request.nextUrl.clone();
|
||||
|
||||
redirectTo.pathname = next;
|
||||
|
||||
// if we have an invite token, we append it to the redirect url
|
||||
if (inviteToken) {
|
||||
// if we have an invite token, we redirect to the join team page
|
||||
// instead of the default next url. This is because the user is trying
|
||||
// to join a team and we want to make sure they are redirected to the
|
||||
// correct page.
|
||||
redirectTo.pathname = pathsConfig.app.joinTeam;
|
||||
redirectTo.searchParams.set('invite_token', inviteToken);
|
||||
}
|
||||
|
||||
if (token_hash && type) {
|
||||
const supabase = getSupabaseRouteHandlerClient();
|
||||
|
||||
const { error } = await supabase.auth.verifyOtp({
|
||||
type,
|
||||
token_hash,
|
||||
const url = await service.verifyTokenHash(request, {
|
||||
joinTeamPath: pathsConfig.app.joinTeam,
|
||||
redirectPath: pathsConfig.app.home,
|
||||
});
|
||||
|
||||
if (!error) {
|
||||
return NextResponse.redirect(redirectTo);
|
||||
}
|
||||
}
|
||||
|
||||
// return the user to an error page with some instructions
|
||||
redirectTo.pathname = '/auth/callback/error';
|
||||
|
||||
return NextResponse.redirect(redirectTo);
|
||||
return NextResponse.redirect(url);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import Head from 'next/head';
|
||||
import { cookies } from 'next/headers';
|
||||
|
||||
import { Toaster } from '@kit/ui/sonner';
|
||||
import { cn } from '@kit/ui/utils';
|
||||
|
||||
import { CsrfTokenMeta } from '~/components/csrf-token-meta';
|
||||
import { RootProviders } from '~/components/root-providers';
|
||||
import { heading, sans } from '~/lib/fonts';
|
||||
import { createI18nServerInstance } from '~/lib/i18n/i18n.server';
|
||||
import { rootMetadata } from '~/lib/root-metdata';
|
||||
import { generateRootMetadata } from '~/lib/root-metdata';
|
||||
|
||||
import '../styles/globals.css';
|
||||
|
||||
@@ -23,10 +21,6 @@ export default async function RootLayout({
|
||||
|
||||
return (
|
||||
<html lang={language} className={className}>
|
||||
<Head>
|
||||
<CsrfTokenMeta />
|
||||
</Head>
|
||||
|
||||
<body>
|
||||
<RootProviders theme={theme} lang={language}>
|
||||
{children}
|
||||
@@ -57,4 +51,4 @@ function getTheme() {
|
||||
return cookies().get('theme')?.value;
|
||||
}
|
||||
|
||||
export const metadata = rootMetadata;
|
||||
export const generateMetadata = generateRootMetadata;
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { headers } from 'next/headers';
|
||||
|
||||
/**
|
||||
* @description This component is used to render the CSRF token as a meta tag.
|
||||
* this tag can be retrieved for use in forms that require CSRF protection.
|
||||
* @constructor
|
||||
*/
|
||||
export function CsrfTokenMeta() {
|
||||
const csrf = headers().get('x-csrf-token') ?? '';
|
||||
|
||||
return <meta content={csrf} name="csrf-token" />;
|
||||
}
|
||||
@@ -1,15 +1,24 @@
|
||||
import { Metadata } from 'next';
|
||||
|
||||
import { headers } from 'next/headers';
|
||||
|
||||
import appConfig from '~/config/app.config';
|
||||
|
||||
/**
|
||||
* @name rootMetadata
|
||||
* @description Define the root metadata for the application.
|
||||
* @name generateRootMetadata
|
||||
* @description Generates the root metadata for the application
|
||||
*/
|
||||
export const rootMetadata: Metadata = {
|
||||
export const generateRootMetadata = (): Metadata => {
|
||||
const csrfToken = headers().get('x-csrf-token') ?? '';
|
||||
|
||||
return {
|
||||
title: appConfig.name,
|
||||
description: appConfig.description,
|
||||
metadataBase: new URL(appConfig.url),
|
||||
applicationName: appConfig.name,
|
||||
other: {
|
||||
'csrf-token': csrfToken,
|
||||
},
|
||||
openGraph: {
|
||||
url: appConfig.url,
|
||||
siteName: appConfig.name,
|
||||
@@ -24,4 +33,5 @@ export const rootMetadata: Metadata = {
|
||||
icon: '/images/favicon/favicon.ico',
|
||||
apple: '/images/favicon/apple-touch-icon.png',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
"./config/edge": "./src/config/sentry.edge.config.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentelemetry/exporter-jaeger": "1.24.1",
|
||||
"@opentelemetry/resources": "1.24.1",
|
||||
"@opentelemetry/sdk-node": "0.51.1",
|
||||
"@opentelemetry/semantic-conventions": "^1.24.1",
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
"./check-requires-mfa": "./src/check-requires-mfa.ts",
|
||||
"./require-user": "./src/require-user.ts",
|
||||
"./hooks/*": "./src/hooks/*.ts",
|
||||
"./database": "./src/database.types.ts"
|
||||
"./database": "./src/database.types.ts",
|
||||
"./auth": "./src/auth.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@kit/eslint-config": "workspace:*",
|
||||
|
||||
188
packages/supabase/src/auth-callback.service.ts
Normal file
188
packages/supabase/src/auth-callback.service.ts
Normal file
@@ -0,0 +1,188 @@
|
||||
import 'server-only';
|
||||
|
||||
import { type EmailOtpType, SupabaseClient } from '@supabase/supabase-js';
|
||||
|
||||
/**
|
||||
* @name createAuthCallbackService
|
||||
* @description Creates an instance of the AuthCallbackService
|
||||
* @param client
|
||||
*/
|
||||
export function createAuthCallbackService(client: SupabaseClient) {
|
||||
return new AuthCallbackService(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name AuthCallbackService
|
||||
* @description Service for handling auth callbacks in Supabase
|
||||
*/
|
||||
class AuthCallbackService {
|
||||
constructor(private readonly client: SupabaseClient) {}
|
||||
|
||||
/**
|
||||
* @name verifyTokenHash
|
||||
* @description Verifies the token hash and type and redirects the user to the next page
|
||||
* This should be used when using a token hash to verify the user's email
|
||||
* @param request
|
||||
* @param params
|
||||
*/
|
||||
async verifyTokenHash(
|
||||
request: Request,
|
||||
params: {
|
||||
joinTeamPath: string;
|
||||
redirectPath: string;
|
||||
errorPath?: string;
|
||||
},
|
||||
): Promise<URL> {
|
||||
const url = new URL(request.url);
|
||||
const searchParams = url.searchParams;
|
||||
|
||||
const token_hash = searchParams.get('token_hash');
|
||||
const type = searchParams.get('type') as EmailOtpType | null;
|
||||
const next = searchParams.get('next') ?? params.redirectPath;
|
||||
const callbackParam = searchParams.get('callback');
|
||||
const callbackUrl = callbackParam ? new URL(callbackParam) : null;
|
||||
const inviteToken = callbackUrl?.searchParams.get('invite_token');
|
||||
|
||||
const errorPath = params.errorPath ?? '/auth/callback/error';
|
||||
|
||||
url.pathname = next;
|
||||
|
||||
// if we have an invite token, we append it to the redirect url
|
||||
if (inviteToken) {
|
||||
// if we have an invite token, we redirect to the join team page
|
||||
// instead of the default next url. This is because the user is trying
|
||||
// to join a team and we want to make sure they are redirected to the
|
||||
// correct page.
|
||||
url.pathname = params.joinTeamPath;
|
||||
searchParams.set('invite_token', inviteToken);
|
||||
}
|
||||
|
||||
if (token_hash && type) {
|
||||
const { error } = await this.client.auth.verifyOtp({
|
||||
type,
|
||||
token_hash,
|
||||
});
|
||||
|
||||
if (!error) {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
// return the user to an error page with some instructions
|
||||
url.pathname = errorPath;
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name exchangeCodeForSession
|
||||
* @description Exchanges the auth code for a session and redirects the user to the next page or an error page
|
||||
* @param request
|
||||
* @param params
|
||||
*/
|
||||
async exchangeCodeForSession(
|
||||
request: Request,
|
||||
params: {
|
||||
joinTeamPath: string;
|
||||
redirectPath: string;
|
||||
errorPath?: string;
|
||||
},
|
||||
): Promise<{
|
||||
nextPath: string;
|
||||
}> {
|
||||
const requestUrl = new URL(request.url);
|
||||
const searchParams = requestUrl.searchParams;
|
||||
|
||||
const authCode = searchParams.get('code');
|
||||
const error = searchParams.get('error');
|
||||
const nextUrlPathFromParams = searchParams.get('next');
|
||||
const inviteToken = searchParams.get('invite_token');
|
||||
const errorPath = params.errorPath ?? '/auth/callback/error';
|
||||
|
||||
let nextUrl = nextUrlPathFromParams ?? params.redirectPath;
|
||||
|
||||
// if we have an invite token, we redirect to the join team page
|
||||
// instead of the default next url. This is because the user is trying
|
||||
// to join a team and we want to make sure they are redirected to the
|
||||
// correct page.
|
||||
if (inviteToken) {
|
||||
nextUrl = `${params.joinTeamPath}?invite_token=${inviteToken}`;
|
||||
}
|
||||
|
||||
if (authCode) {
|
||||
try {
|
||||
const { error } =
|
||||
await this.client.auth.exchangeCodeForSession(authCode);
|
||||
|
||||
// if we have an error, we redirect to the error page
|
||||
if (error) {
|
||||
return onError({
|
||||
error: error.message,
|
||||
path: errorPath,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
{
|
||||
error,
|
||||
name: `auth.callback`,
|
||||
},
|
||||
`An error occurred while exchanging code for session`,
|
||||
);
|
||||
|
||||
const message = error instanceof Error ? error.message : error;
|
||||
|
||||
return onError({
|
||||
error: message as string,
|
||||
path: errorPath,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return onError({
|
||||
error,
|
||||
path: errorPath,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
nextPath: nextUrl,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function onError({ error, path }: { error: string; path: string }) {
|
||||
const errorMessage = getAuthErrorMessage(error);
|
||||
|
||||
console.error(
|
||||
{
|
||||
error,
|
||||
name: `auth.callback`,
|
||||
},
|
||||
`An error occurred while signing user in`,
|
||||
);
|
||||
|
||||
const nextPath = `${path}?error=${errorMessage}`;
|
||||
|
||||
return {
|
||||
nextPath,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given error message indicates a verifier error.
|
||||
* We check for this specific error because it's highly likely that the
|
||||
* user is trying to sign in using a different browser than the one they
|
||||
* used to request the sign in link. This is a common mistake, so we
|
||||
* want to provide a helpful error message.
|
||||
*/
|
||||
function isVerifierError(error: string) {
|
||||
return error.includes('both auth code and code verifier should be non-empty');
|
||||
}
|
||||
|
||||
function getAuthErrorMessage(error: string) {
|
||||
return isVerifierError(error)
|
||||
? `auth:errors.codeVerifierMismatch`
|
||||
: `auth:authenticationErrorAlertBody`;
|
||||
}
|
||||
1
packages/supabase/src/auth.ts
Normal file
1
packages/supabase/src/auth.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './auth-callback.service';
|
||||
115
pnpm-lock.yaml
generated
115
pnpm-lock.yaml
generated
@@ -1039,6 +1039,9 @@ importers:
|
||||
|
||||
packages/monitoring/sentry:
|
||||
dependencies:
|
||||
'@opentelemetry/exporter-jaeger':
|
||||
specifier: 1.24.1
|
||||
version: 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/resources':
|
||||
specifier: 1.24.1
|
||||
version: 1.24.1(@opentelemetry/api@1.8.0)
|
||||
@@ -1959,6 +1962,12 @@ packages:
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': '>=1.0.0 <1.9.0'
|
||||
|
||||
'@opentelemetry/exporter-jaeger@1.24.1':
|
||||
resolution: {integrity: sha512-zrcY76PVR4itZD2oxQdFgnvS/Lst1CxmMofOhngvTDIXVqSTEf00QfmdIQUljwmycYwxZIvbJ445k3AGRBbZKQ==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@opentelemetry/api': ^1.0.0
|
||||
|
||||
'@opentelemetry/exporter-trace-otlp-grpc@0.50.0':
|
||||
resolution: {integrity: sha512-w/NF4TrwHxx+Uz1M0rCOSVr6KgcoQPv3zF9JRqcebY2euD7ddWnLP0hE8JavyA1uq4UchnMp9faAk9n7hTCePw==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -4191,6 +4200,9 @@ packages:
|
||||
ajv@6.12.6:
|
||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||
|
||||
ansi-color@0.2.1:
|
||||
resolution: {integrity: sha512-bF6xLaZBLpOQzgYUtYEhJx090nPSZk1BQ/q2oyBK9aMMcJHzx9uXGCjI2Y+LebsN4Jwoykr0V9whbPiogdyHoQ==}
|
||||
|
||||
ansi-escapes@4.3.2:
|
||||
resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -4353,6 +4365,10 @@ packages:
|
||||
buffer@6.0.3:
|
||||
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
|
||||
|
||||
bufrw@1.4.0:
|
||||
resolution: {integrity: sha512-sWm8iPbqvL9+5SiYxXH73UOkyEbGQg7kyHQmReF89WJHQJw2eV4P/yZ0E+b71cczJ4pPobVhXxgQcmfSTgGHxQ==}
|
||||
engines: {node: '>= 0.10.x'}
|
||||
|
||||
builtins@1.0.3:
|
||||
resolution: {integrity: sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==}
|
||||
|
||||
@@ -4826,6 +4842,9 @@ packages:
|
||||
error-ex@1.3.2:
|
||||
resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
|
||||
|
||||
error@7.0.2:
|
||||
resolution: {integrity: sha512-UtVv4l5MhijsYUxPJo4390gzfZvAnTHreNnDjnTZaKIiZ/SemXxAhBkYSKtWa5RtBXbLP8tMgn/n0RUa/H7jXw==}
|
||||
|
||||
es-abstract@1.23.3:
|
||||
resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -5318,6 +5337,11 @@ packages:
|
||||
header-case@1.0.1:
|
||||
resolution: {integrity: sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==}
|
||||
|
||||
hexer@1.5.0:
|
||||
resolution: {integrity: sha512-dyrPC8KzBzUJ19QTIo1gXNqIISRXQ0NwteW6OeQHRN4ZuZeHkdODfj0zHBdOlHbRY8GqbqK57C9oWSvQZizFsg==}
|
||||
engines: {node: '>= 0.10.x'}
|
||||
hasBin: true
|
||||
|
||||
hoist-non-react-statics@3.3.2:
|
||||
resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
|
||||
|
||||
@@ -5629,6 +5653,10 @@ packages:
|
||||
resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
jaeger-client@3.19.0:
|
||||
resolution: {integrity: sha512-M0c7cKHmdyEUtjemnJyx/y9uX16XHocL46yQvyqDlPdvAcwPDbHrIbKjQdBqtiE4apQ/9dmr+ZLJYYPGnurgpw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
javascript-natural-sort@0.7.1:
|
||||
resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==}
|
||||
|
||||
@@ -5766,6 +5794,10 @@ packages:
|
||||
resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
long@2.4.0:
|
||||
resolution: {integrity: sha512-ijUtjmO/n2A5PaosNG9ZGDsQ3vxJg7ZW8vsY8Kp0f2yIZWhSJvjmegV7t+9RPQKxKrvj8yKGehhS+po14hPLGQ==}
|
||||
engines: {node: '>=0.6'}
|
||||
|
||||
long@5.2.3:
|
||||
resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==}
|
||||
|
||||
@@ -6153,6 +6185,9 @@ packages:
|
||||
node-html-parser@6.1.13:
|
||||
resolution: {integrity: sha512-qIsTMOY4C/dAa5Q5vsobRpOOvPfC4pB61UVW2uSwZNUp0QU/jCekTal1vMmbO0DgdHeLUJpv/ARmDqErVxA3Sg==}
|
||||
|
||||
node-int64@0.4.0:
|
||||
resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==}
|
||||
|
||||
node-plop@0.26.3:
|
||||
resolution: {integrity: sha512-Cov028YhBZ5aB7MdMWJEmwyBig43aGL5WT4vdoB28Oitau1zZAcHUn8Sgfk9HM33TqhtLJ9PlM/O0Mv+QpV/4Q==}
|
||||
engines: {node: '>=8.9.4'}
|
||||
@@ -6250,6 +6285,10 @@ packages:
|
||||
resolution: {integrity: sha512-aiSt/4ubOTyb1N5C2ZbGrBvaJOXIZhZvpRPYuUVxQJe27wJZqf/o65iPrqgLcgfeOLaQ8cS2Q+762jrYvniTrA==}
|
||||
engines: {node: '>18.0.0'}
|
||||
|
||||
opentracing@0.14.7:
|
||||
resolution: {integrity: sha512-vz9iS7MJ5+Bp1URw8Khvdyw1H/hGvzHWlKQ7eRrQojSCDL1/SrWfrY9QebLw97n2deyRtzHRC3MkQfVNUCo91Q==}
|
||||
engines: {node: '>=0.10'}
|
||||
|
||||
optionator@0.9.4:
|
||||
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
@@ -6558,6 +6597,10 @@ packages:
|
||||
process-warning@3.0.0:
|
||||
resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==}
|
||||
|
||||
process@0.10.1:
|
||||
resolution: {integrity: sha512-dyIett8dgGIZ/TXKUzeYExt7WA6ldDzys9vTDU/cCA9L17Ypme+KzS+NjQCjpn9xsvi/shbMC+yP/BcFMBz0NA==}
|
||||
engines: {node: '>= 0.6.0'}
|
||||
|
||||
process@0.11.10:
|
||||
resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
|
||||
engines: {node: '>= 0.6.0'}
|
||||
@@ -7046,6 +7089,9 @@ packages:
|
||||
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
||||
string-template@0.2.1:
|
||||
resolution: {integrity: sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw==}
|
||||
|
||||
string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -7206,6 +7252,11 @@ packages:
|
||||
thread-stream@3.0.0:
|
||||
resolution: {integrity: sha512-oUIFjxaUT6knhPtWgDMc29zF1FcSl0yXpapkyrQrCGEfYA2HUZXCilUtKyYIv6HkCyqSPAMkY+EG0GbyIrNDQg==}
|
||||
|
||||
thriftrw@3.11.4:
|
||||
resolution: {integrity: sha512-UcuBd3eanB3T10nXWRRMwfwoaC6VMk7qe3/5YIWP2Jtw+EbHqJ0p1/K3x8ixiR5dozKSSfcg1W+0e33G1Di3XA==}
|
||||
engines: {node: '>= 0.10.x'}
|
||||
hasBin: true
|
||||
|
||||
through@2.3.8:
|
||||
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
|
||||
|
||||
@@ -7447,6 +7498,10 @@ packages:
|
||||
util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
uuid@8.3.2:
|
||||
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
||||
hasBin: true
|
||||
|
||||
uuid@9.0.1:
|
||||
resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==}
|
||||
hasBin: true
|
||||
@@ -7599,6 +7654,9 @@ packages:
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
xorshift@1.2.0:
|
||||
resolution: {integrity: sha512-iYgNnGyeeJ4t6U11NpA/QiKy+PXn5Aa3Azg5qkwIFz1tBLllQrjjsk9yzD7IAK0naNU4JxdeDgqW9ov4u/hc4g==}
|
||||
|
||||
xtend@4.0.2:
|
||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||
engines: {node: '>=0.4'}
|
||||
@@ -8464,6 +8522,14 @@ snapshots:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
|
||||
'@opentelemetry/exporter-jaeger@1.24.1(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@opentelemetry/api': 1.8.0
|
||||
'@opentelemetry/core': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/sdk-trace-base': 1.24.1(@opentelemetry/api@1.8.0)
|
||||
'@opentelemetry/semantic-conventions': 1.24.1
|
||||
jaeger-client: 3.19.0
|
||||
|
||||
'@opentelemetry/exporter-trace-otlp-grpc@0.50.0(@opentelemetry/api@1.8.0)':
|
||||
dependencies:
|
||||
'@grpc/grpc-js': 1.10.7
|
||||
@@ -11513,6 +11579,8 @@ snapshots:
|
||||
json-schema-traverse: 0.4.1
|
||||
uri-js: 4.4.1
|
||||
|
||||
ansi-color@0.2.1: {}
|
||||
|
||||
ansi-escapes@4.3.2:
|
||||
dependencies:
|
||||
type-fest: 0.21.3
|
||||
@@ -11717,6 +11785,13 @@ snapshots:
|
||||
base64-js: 1.5.1
|
||||
ieee754: 1.2.1
|
||||
|
||||
bufrw@1.4.0:
|
||||
dependencies:
|
||||
ansi-color: 0.2.1
|
||||
error: 7.0.2
|
||||
hexer: 1.5.0
|
||||
xtend: 4.0.2
|
||||
|
||||
builtins@1.0.3: {}
|
||||
|
||||
busboy@1.6.0:
|
||||
@@ -12178,6 +12253,11 @@ snapshots:
|
||||
dependencies:
|
||||
is-arrayish: 0.2.1
|
||||
|
||||
error@7.0.2:
|
||||
dependencies:
|
||||
string-template: 0.2.1
|
||||
xtend: 4.0.2
|
||||
|
||||
es-abstract@1.23.3:
|
||||
dependencies:
|
||||
array-buffer-byte-length: 1.0.1
|
||||
@@ -12810,6 +12890,13 @@ snapshots:
|
||||
no-case: 2.3.2
|
||||
upper-case: 1.1.3
|
||||
|
||||
hexer@1.5.0:
|
||||
dependencies:
|
||||
ansi-color: 0.2.1
|
||||
minimist: 1.2.8
|
||||
process: 0.10.1
|
||||
xtend: 4.0.2
|
||||
|
||||
hoist-non-react-statics@3.3.2:
|
||||
dependencies:
|
||||
react-is: 16.13.1
|
||||
@@ -13155,6 +13242,14 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@pkgjs/parseargs': 0.11.0
|
||||
|
||||
jaeger-client@3.19.0:
|
||||
dependencies:
|
||||
node-int64: 0.4.0
|
||||
opentracing: 0.14.7
|
||||
thriftrw: 3.11.4
|
||||
uuid: 8.3.2
|
||||
xorshift: 1.2.0
|
||||
|
||||
javascript-natural-sort@0.7.1: {}
|
||||
|
||||
jest-worker@27.5.1:
|
||||
@@ -13275,6 +13370,8 @@ snapshots:
|
||||
chalk: 4.1.2
|
||||
is-unicode-supported: 0.1.0
|
||||
|
||||
long@2.4.0: {}
|
||||
|
||||
long@5.2.3: {}
|
||||
|
||||
longest-streak@3.1.0: {}
|
||||
@@ -13894,6 +13991,8 @@ snapshots:
|
||||
css-select: 5.1.0
|
||||
he: 1.2.0
|
||||
|
||||
node-int64@0.4.0: {}
|
||||
|
||||
node-plop@0.26.3:
|
||||
dependencies:
|
||||
'@babel/runtime-corejs3': 7.24.5
|
||||
@@ -13999,6 +14098,8 @@ snapshots:
|
||||
- supports-color
|
||||
optional: true
|
||||
|
||||
opentracing@0.14.7: {}
|
||||
|
||||
optionator@0.9.4:
|
||||
dependencies:
|
||||
deep-is: 0.1.4
|
||||
@@ -14276,6 +14377,8 @@ snapshots:
|
||||
|
||||
process-warning@3.0.0: {}
|
||||
|
||||
process@0.10.1: {}
|
||||
|
||||
process@0.11.10: {}
|
||||
|
||||
progress@2.0.3: {}
|
||||
@@ -14826,6 +14929,8 @@ snapshots:
|
||||
|
||||
streamsearch@1.1.0: {}
|
||||
|
||||
string-template@0.2.1: {}
|
||||
|
||||
string-width@4.2.3:
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
@@ -15027,6 +15132,12 @@ snapshots:
|
||||
dependencies:
|
||||
real-require: 0.2.0
|
||||
|
||||
thriftrw@3.11.4:
|
||||
dependencies:
|
||||
bufrw: 1.4.0
|
||||
error: 7.0.2
|
||||
long: 2.4.0
|
||||
|
||||
through@2.3.8: {}
|
||||
|
||||
tiny-invariant@1.0.6: {}
|
||||
@@ -15272,6 +15383,8 @@ snapshots:
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
uuid@8.3.2: {}
|
||||
|
||||
uuid@9.0.1: {}
|
||||
|
||||
v8-compile-cache-lib@3.0.1: {}
|
||||
@@ -15469,6 +15582,8 @@ snapshots:
|
||||
|
||||
ws@8.17.0: {}
|
||||
|
||||
xorshift@1.2.0: {}
|
||||
|
||||
xtend@4.0.2: {}
|
||||
|
||||
y-prosemirror@1.2.3(prosemirror-model@1.21.0)(prosemirror-state@1.4.3)(prosemirror-view@1.33.6)(y-protocols@1.0.6(yjs@13.6.15))(yjs@13.6.15):
|
||||
|
||||
Reference in New Issue
Block a user