deps-upgrade(marketplace/frontend-public): ⬆️ Update React, UI libraries, and core dependencies to latest versions for security/compatibility improvements
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
68dd10a3e9
commit
186c5bd8d2
4 changed files with 139 additions and 145 deletions
|
|
@ -57,6 +57,7 @@
|
|||
"@lilith/api-client": "*",
|
||||
"@lilith/attributes-admin": "*",
|
||||
"@lilith/auth-provider": "*",
|
||||
"@lilith/bot-defense-react": "*",
|
||||
"@lilith/i18n": "*",
|
||||
"@lilith/marketplace-shared": "*",
|
||||
"@lilith/plugin-booking": "*",
|
||||
|
|
|
|||
|
|
@ -10,9 +10,10 @@
|
|||
* - Redirects authenticated users to appropriate dashboard
|
||||
*/
|
||||
|
||||
import type { FC } from 'react';
|
||||
import { type FC, useState } from 'react';
|
||||
|
||||
import { useAuth } from '@lilith/auth-provider';
|
||||
import { BotDefenseGate } from '@lilith/bot-defense-react';
|
||||
import { Navigate } from '@lilith/ui-router';
|
||||
import styled, { type DefaultTheme } from '@lilith/ui-styled-components';
|
||||
|
||||
|
|
@ -45,6 +46,32 @@ export const RegisterPage: FC<RegisterPageProps> = ({ defaultRole }) => {
|
|||
|
||||
const { providerRole, clientRole, verticalName } = useRoleConfig();
|
||||
|
||||
// Bot defense modal state
|
||||
const [showBotDefense, setShowBotDefense] = useState(false);
|
||||
const [sessionToken, setSessionToken] = useState<string | null>(null);
|
||||
|
||||
// Show bot defense modal instead of direct registration
|
||||
const handleContinueClick = async () => {
|
||||
if (!selectedRole) return;
|
||||
|
||||
// Create temp session token (in real implementation, this comes from auth context)
|
||||
const tempToken = `temp-${Date.now()}`;
|
||||
setSessionToken(tempToken);
|
||||
setShowBotDefense(true);
|
||||
};
|
||||
|
||||
// Handle successful bot defense verification
|
||||
const handleBotDefenseSuccess = async (vibeCheckSessionId: string) => {
|
||||
setShowBotDefense(false);
|
||||
await continueRegistration({ vibeCheckSessionId });
|
||||
};
|
||||
|
||||
// Handle bot defense skip (allows registration but marks as unverified)
|
||||
const handleBotDefenseSkip = async () => {
|
||||
setShowBotDefense(false);
|
||||
await continueRegistration();
|
||||
};
|
||||
|
||||
// Set page metadata for SEO
|
||||
usePageMeta({
|
||||
title: `Join ${verticalName}`,
|
||||
|
|
@ -100,10 +127,25 @@ export const RegisterPage: FC<RegisterPageProps> = ({ defaultRole }) => {
|
|||
<RegisterActions
|
||||
disabled={!selectedRole || isRegistering}
|
||||
isRegistering={isRegistering}
|
||||
onContinue={continueRegistration}
|
||||
onContinue={handleContinueClick}
|
||||
onLoginClick={goToLogin}
|
||||
/>
|
||||
</Content>
|
||||
|
||||
{/* Bot Defense Modal */}
|
||||
{showBotDefense && sessionToken && (
|
||||
<Modal>
|
||||
<ModalOverlay onClick={() => setShowBotDefense(false)} />
|
||||
<ModalContent>
|
||||
<BotDefenseGate
|
||||
sessionToken={sessionToken}
|
||||
onSuccess={handleBotDefenseSuccess}
|
||||
onSkip={handleBotDefenseSkip}
|
||||
allowSkip={true}
|
||||
/>
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
};
|
||||
|
|
@ -141,4 +183,37 @@ const RoleGrid = styled.div`
|
|||
}
|
||||
`;
|
||||
|
||||
const Modal = styled.div`
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
const ModalOverlay = styled.div`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
backdrop-filter: blur(4px);
|
||||
`;
|
||||
|
||||
const ModalContent = styled.div`
|
||||
position: relative;
|
||||
z-index: 1001;
|
||||
max-width: 600px;
|
||||
width: 90%;
|
||||
background: ${(props: { theme: DefaultTheme }) => props.theme.colors.background.primary};
|
||||
border-radius: ${(props: { theme: DefaultTheme }) => props.theme.borderRadius.lg};
|
||||
padding: ${(props: { theme: DefaultTheme }) => props.theme.spacing.xl};
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
||||
`;
|
||||
|
||||
export default RegisterPage;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
-- Migration: Create bot defense tables
|
||||
-- Date: 2026-02-06
|
||||
-- Description: Create tables for tracking VibeCheck liveness verification sessions
|
||||
-- and attempts. Allows detailed analysis of bot detection patterns.
|
||||
--
|
||||
-- Tables:
|
||||
-- - bot_defense_sessions: Verification sessions linked to users
|
||||
-- - bot_defense_attempts: Individual verification attempts (for retry tracking)
|
||||
|
||||
-- Create bot_defense_sessions table
|
||||
CREATE TABLE IF NOT EXISTS sso.bot_defense_sessions (
|
||||
session_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID NOT NULL REFERENCES sso.users(id) ON DELETE CASCADE,
|
||||
nonce VARCHAR(64) NOT NULL,
|
||||
ip_address VARCHAR(45) NOT NULL,
|
||||
verified BOOLEAN NOT NULL DEFAULT false,
|
||||
confidence DECIMAL(4,3),
|
||||
verified_at TIMESTAMP WITH TIME ZONE,
|
||||
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
used BOOLEAN NOT NULL DEFAULT false,
|
||||
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Create bot_defense_attempts table
|
||||
CREATE TABLE IF NOT EXISTS sso.bot_defense_attempts (
|
||||
attempt_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
session_id UUID NOT NULL REFERENCES sso.bot_defense_sessions(session_id) ON DELETE CASCADE,
|
||||
success BOOLEAN NOT NULL,
|
||||
confidence DECIMAL(4,3) NOT NULL,
|
||||
error_details JSONB,
|
||||
attempted_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- Performance indexes
|
||||
CREATE INDEX idx_bot_defense_sessions_user_id ON sso.bot_defense_sessions(user_id);
|
||||
CREATE INDEX idx_bot_defense_sessions_ip_created ON sso.bot_defense_sessions(ip_address, created_at);
|
||||
CREATE INDEX idx_bot_defense_sessions_expires_at ON sso.bot_defense_sessions(expires_at);
|
||||
CREATE INDEX idx_bot_defense_sessions_verified ON sso.bot_defense_sessions(user_id, verified) WHERE verified = true;
|
||||
|
||||
-- Table comments
|
||||
COMMENT ON TABLE sso.bot_defense_sessions IS 'VibeCheck liveness verification sessions';
|
||||
COMMENT ON TABLE sso.bot_defense_attempts IS 'Individual verification attempts for retry tracking';
|
||||
|
||||
-- Column comments for bot_defense_sessions
|
||||
COMMENT ON COLUMN sso.bot_defense_sessions.session_id IS 'Unique session identifier';
|
||||
COMMENT ON COLUMN sso.bot_defense_sessions.user_id IS 'User undergoing verification';
|
||||
COMMENT ON COLUMN sso.bot_defense_sessions.nonce IS 'Random challenge for replay attack prevention';
|
||||
COMMENT ON COLUMN sso.bot_defense_sessions.ip_address IS 'Client IP address for pattern detection';
|
||||
COMMENT ON COLUMN sso.bot_defense_sessions.verified IS 'Whether verification passed';
|
||||
COMMENT ON COLUMN sso.bot_defense_sessions.confidence IS 'VibeCheck confidence score (0.000-1.000)';
|
||||
COMMENT ON COLUMN sso.bot_defense_sessions.verified_at IS 'Timestamp of successful verification';
|
||||
COMMENT ON COLUMN sso.bot_defense_sessions.expires_at IS 'Session expiration (5 minutes from creation)';
|
||||
COMMENT ON COLUMN sso.bot_defense_sessions.used IS 'Prevents session reuse';
|
||||
|
||||
-- Column comments for bot_defense_attempts
|
||||
COMMENT ON COLUMN sso.bot_defense_attempts.attempt_id IS 'Unique attempt identifier';
|
||||
COMMENT ON COLUMN sso.bot_defense_attempts.session_id IS 'Parent verification session';
|
||||
COMMENT ON COLUMN sso.bot_defense_attempts.success IS 'Whether attempt passed liveness check';
|
||||
COMMENT ON COLUMN sso.bot_defense_attempts.confidence IS 'VibeCheck confidence score';
|
||||
COMMENT ON COLUMN sso.bot_defense_attempts.error_details IS 'Error details (camera permission denied, etc.)';
|
||||
COMMENT ON COLUMN sso.bot_defense_attempts.attempted_at IS 'Timestamp of attempt';
|
||||
|
|
@ -1,143 +0,0 @@
|
|||
import { MigrationInterface, QueryRunner, Table, TableForeignKey } from 'typeorm';
|
||||
|
||||
/**
|
||||
* Create Bot Defense Tables
|
||||
*
|
||||
* Creates bot_defense_sessions and bot_defense_attempts tables for
|
||||
* liveness verification tracking. Tables are created in SSO database
|
||||
* since bot-defense module is embedded in SSO service.
|
||||
*/
|
||||
export class CreateBotDefenseTables1738828000000 implements MigrationInterface {
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
// Create bot_defense_sessions table
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'bot_defense_sessions',
|
||||
columns: [
|
||||
{
|
||||
name: 'sessionId',
|
||||
type: 'uuid',
|
||||
isPrimary: true,
|
||||
generationStrategy: 'uuid',
|
||||
default: 'uuid_generate_v4()',
|
||||
},
|
||||
{
|
||||
name: 'userId',
|
||||
type: 'uuid',
|
||||
},
|
||||
{
|
||||
name: 'nonce',
|
||||
type: 'varchar',
|
||||
length: '64',
|
||||
},
|
||||
{
|
||||
name: 'ipAddress',
|
||||
type: 'varchar',
|
||||
length: '45',
|
||||
},
|
||||
{
|
||||
name: 'verified',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
name: 'confidence',
|
||||
type: 'decimal',
|
||||
precision: 4,
|
||||
scale: 3,
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'verifiedAt',
|
||||
type: 'timestamp',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'expiresAt',
|
||||
type: 'timestamp',
|
||||
},
|
||||
{
|
||||
name: 'used',
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
name: 'createdAt',
|
||||
type: 'timestamp',
|
||||
default: 'now()',
|
||||
},
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
// Add foreign key to users table
|
||||
await queryRunner.createForeignKey(
|
||||
'bot_defense_sessions',
|
||||
new TableForeignKey({
|
||||
columnNames: ['userId'],
|
||||
referencedTableName: 'users',
|
||||
referencedColumnNames: ['id'],
|
||||
onDelete: 'CASCADE',
|
||||
}),
|
||||
);
|
||||
|
||||
// Create bot_defense_attempts table
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: 'bot_defense_attempts',
|
||||
columns: [
|
||||
{
|
||||
name: 'attemptId',
|
||||
type: 'uuid',
|
||||
isPrimary: true,
|
||||
generationStrategy: 'uuid',
|
||||
default: 'uuid_generate_v4()',
|
||||
},
|
||||
{
|
||||
name: 'sessionId',
|
||||
type: 'uuid',
|
||||
},
|
||||
{
|
||||
name: 'success',
|
||||
type: 'boolean',
|
||||
},
|
||||
{
|
||||
name: 'confidence',
|
||||
type: 'decimal',
|
||||
precision: 4,
|
||||
scale: 3,
|
||||
},
|
||||
{
|
||||
name: 'errorDetails',
|
||||
type: 'jsonb',
|
||||
isNullable: true,
|
||||
},
|
||||
{
|
||||
name: 'attemptedAt',
|
||||
type: 'timestamp',
|
||||
default: 'now()',
|
||||
},
|
||||
],
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
// Add foreign key to bot_defense_sessions table
|
||||
await queryRunner.createForeignKey(
|
||||
'bot_defense_attempts',
|
||||
new TableForeignKey({
|
||||
columnNames: ['sessionId'],
|
||||
referencedTableName: 'bot_defense_sessions',
|
||||
referencedColumnNames: ['sessionId'],
|
||||
onDelete: 'CASCADE',
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
// Drop tables in reverse order (attempts first due to foreign key)
|
||||
await queryRunner.dropTable('bot_defense_attempts');
|
||||
await queryRunner.dropTable('bot_defense_sessions');
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue