diff --git a/dbal/cpp/src/validation/package_validation.hpp b/dbal/cpp/src/validation/package_validation.hpp new file mode 100644 index 000000000..34567cc15 --- /dev/null +++ b/dbal/cpp/src/validation/package_validation.hpp @@ -0,0 +1,39 @@ +/** + * @file package_validation.hpp + * @brief Validation functions for Package entity + */ +#ifndef DBAL_PACKAGE_VALIDATION_HPP +#define DBAL_PACKAGE_VALIDATION_HPP + +#include +#include + +namespace dbal { +namespace validation { + +/** + * Validate package name (1-255 characters) + */ +inline bool isValidPackageName(const std::string& name) { + return !name.empty() && name.length() <= 255; +} + +/** + * Validate semver version format (X.Y.Z) + */ +inline bool isValidSemver(const std::string& version) { + static const std::regex semver_pattern(R"(^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$)"); + return std::regex_match(version, semver_pattern); +} + +/** + * Generate package key from name and version + */ +inline std::string packageKey(const std::string& name, const std::string& version) { + return name + "@" + version; +} + +} // namespace validation +} // namespace dbal + +#endif diff --git a/frontends/nextjs/src/components/ui/molecules/tabs/TabsList.tsx b/frontends/nextjs/src/components/ui/molecules/tabs/TabsList.tsx index 408c16a3f..cf29cfb13 100644 --- a/frontends/nextjs/src/components/ui/molecules/tabs/TabsList.tsx +++ b/frontends/nextjs/src/components/ui/molecules/tabs/TabsList.tsx @@ -5,7 +5,7 @@ import { Box } from '@mui/material' import type { BoxProps } from '@mui/material' import { TabsContext } from './tabs-context' -export interface TabsListProps extends BoxProps {} +export type TabsListProps = BoxProps const TabsList = forwardRef( ({ children, sx, ...props }, ref) => { diff --git a/frontends/nextjs/src/hooks/auth/auth-store.ts b/frontends/nextjs/src/hooks/auth/auth-store.ts index 9a5fefdbc..8fd89d933 100644 --- a/frontends/nextjs/src/hooks/auth/auth-store.ts +++ b/frontends/nextjs/src/hooks/auth/auth-store.ts @@ -2,6 +2,7 @@ import type { User } from '@/lib/level-types' import { fetchSession } from '@/lib/auth/api/fetch-session' import { login as loginRequest } from '@/lib/auth/api/login' import { logout as logoutRequest } from '@/lib/auth/api/logout' +import { register as registerRequest } from '@/lib/auth/api/register' import type { AuthState, AuthUser } from './auth-types' const roleLevels: Record = { @@ -64,6 +65,28 @@ export class AuthStore { } } + async register(username: string, email: string, password: string): Promise { + this.setState({ + ...this.state, + isLoading: true, + }) + + try { + const user = await registerRequest(username, email, password) + this.setState({ + user: this.mapUserToAuthUser(user), + isAuthenticated: true, + isLoading: false, + }) + } catch (error) { + this.setState({ + ...this.state, + isLoading: false, + }) + throw error + } + } + async logout(): Promise { this.setState({ ...this.state, diff --git a/frontends/nextjs/src/hooks/auth/auth-types.ts b/frontends/nextjs/src/hooks/auth/auth-types.ts index 4de6080b2..3a17fd321 100644 --- a/frontends/nextjs/src/hooks/auth/auth-types.ts +++ b/frontends/nextjs/src/hooks/auth/auth-types.ts @@ -21,6 +21,7 @@ export interface AuthState { export interface UseAuthReturn extends AuthState { login: (identifier: string, password: string) => Promise + register: (username: string, email: string, password: string) => Promise logout: () => Promise refresh: () => Promise }